[Templates-cvs] cvs commit: Template2/t/vmethods hash.t list.t replace.t text.t

cvs@template-toolkit.org cvs@template-toolkit.org


cvs         06/02/02 11:35:10

  Added:       t/vmethods hash.t list.t replace.t text.t
  Log:
  * moved vmethods tests into vmethods/*
  * added vmethods/replace.t to test new replace method
  
  Revision  Changes    Path
  1.1                  Template2/t/vmethods/hash.t
  
  Index: hash.t
  ===================================================================
  #============================================================= -*-perl-*-
  #
  # t/vmethods/hash.t
  #
  # Testing hash virtual variable methods.
  #
  # Written by Andy Wardley <abw@cpan.org>
  #
  # Copyright (C) 1996-2006 Andy Wardley.  All Rights Reserved.
  #
  # This is free software; you can redistribute it and/or modify it
  # under the same terms as Perl itself.
  #
  # $Id: hash.t,v 1.1 2006/02/02 11:35:07 abw Exp $
  #
  #========================================================================
  
  use strict;
  use warnings;
  use lib qw( ./lib ../lib ../../lib );
  use Template::Test;
  
  # make sure we're using the Perl stash
  $Template::Config::STASH = 'Template::Stash';
  
  my $params = {
      hash      => { a => 'b', c => 'd' },
      uhash     => { tobe => '2b', nottobe => undef },
  };
  
  my $tt = Template->new();
  my $tc = $tt->context();
  
  $tc->define_vmethod(hash   => dump => sub {
          my $hash = shift;
          return '{ ' 
              . join(', ', map { "$_ => '$hash->{$_}'" } sort keys %$hash)
              . ' }';
  });
  
  test_expect(\*DATA, undef, $params);
  
  __DATA__
  
  #------------------------------------------------------------------------
  # hash virtual methods
  #------------------------------------------------------------------------
  
  -- test --
  -- name hash keys --
  [% hash.keys.sort.join(', ') %]
  -- expect --
  a, c
  
  -- test --
  -- name hash values --
  [% hash.values.sort.join(', ') %]
  -- expect --
  b, d
  
  -- test --
  -- name hash each --
  [% hash.each.sort.join(', ') %]
  -- expect --
  a, b, c, d
  
  -- test --
  -- name hash items --
  [% hash.items.sort.join(', ') %]
  -- expect --
  a, b, c, d
  
  -- test --
  -- name hash size --
  [% hash.size %]
  -- expect --
  2
  
  -- test --
  [% hash.defined('a') ? 'good' : 'bad' %]
  [% hash.a.defined ? 'good' : 'bad' %]
  [% hash.defined('x') ? 'bad' : 'good' %]
  [% hash.x.defined ? 'bad' : 'good' %]
  [% hash.defined ? 'good def' : 'bad def' %]
  [% no_such_hash.defined ? 'bad no def' : 'good no def' %]
  -- expect --
  good
  good
  good
  good
  good def
  good no def
  
  -- test --
  [% uhash.defined('tobe') ? 'good' : 'bad' %]
  [% uhash.tobe.defined ? 'good' : 'bad' %]
  [% uhash.exists('tobe') ? 'good' : 'bad' %]
  [% uhash.defined('nottobe') ? 'bad' : 'good' %]
  [% hash.nottobe.defined ? 'bad' : 'good' %]
  [% uhash.exists('nottobe') ? 'good' : 'bad' %]
  -- expect --
  good
  good
  good
  good
  good
  good
  
  -- test --
  -- name hash.pairs --
  [% FOREACH pair IN hash.pairs -%]
  * [% pair.key %] => [% pair.value %]
  [% END %]
  -- expect --
  * a => b
  * c => d
  
  -- test --
  -- name hash.list (old style) --
  [% FOREACH pair IN hash.list -%]
  * [% pair.key %] => [% pair.value %]
  [% END %]
  -- expect --
  * a => b
  * c => d
  
  
  
  #------------------------------------------------------------------------
  # user defined hash virtual methods
  #------------------------------------------------------------------------
  
  -- test --
  -- name dump hash --
  [% product = {
       id = 'abc-123',
       name = 'ABC Widget #123'
       price = 7.99
     };
     product.dump
  %]
  -- expect --
  { id => 'abc-123', name => 'ABC Widget #123', price => '7.99' }
  
  
  
  
  
  
  
  
  1.1                  Template2/t/vmethods/list.t
  
  Index: list.t
  ===================================================================
  #============================================================= -*-perl-*-
  #
  # t/vmethods/list.t
  #
  # Testing list virtual variable methods.
  #
  # Written by Andy Wardley <abw@cpan.org>
  #
  # Copyright (C) 1996-2006 Andy Wardley.  All Rights Reserved.
  #
  # This is free software; you can redistribute it and/or modify it
  # under the same terms as Perl itself.
  #
  # $Id: list.t,v 1.1 2006/02/02 11:35:07 abw Exp $
  #
  #========================================================================
  
  use strict;
  use warnings;
  use lib qw( ./lib ../lib ../../lib );
  use Template::Test;
  
  # make sure we're using the Perl stash
  $Template::Config::STASH = 'Template::Stash';
  
  # add some new list ops
  $Template::Stash::LIST_OPS->{ sum    } = \&sum;
  $Template::Stash::LIST_OPS->{ odd    } = \&odd;
  $Template::Stash::LIST_OPS->{ jumble } = \&jumble;
  
  # make sure we're using the Perl stash
  $Template::Config::STASH = 'Template::Stash';
  
  
  #------------------------------------------------------------------------
  # define a simple object to test sort vmethod calling object method
  #------------------------------------------------------------------------
  
  package My::Object;
  
  sub new { 
      my ($class, $name) = @_;
      bless {
          _NAME => $name,
      }, $class;
  }
  sub name { 
      my $self = shift;
      return $self->{ _NAME };
  }
  
  #------------------------------------------------------------------------
  
  package main;
  
  sub sum {
      my $list = shift;
      my $n = 0;
      foreach (@$list) {
          $n += $_;
      }
      return $n;
  }
  
  sub odd {
      my $list = shift;
      return [ grep { $_ % 2 } @$list ];
  }
  
  sub jumble {
      my ($list, $chop) = @_;
      $chop = 1 unless defined $chop;
      return $list unless @$list > 3;
      push(@$list, splice(@$list, 0, $chop));
      return $list;
  }
  
  my $params = {
      metavars => [ qw( foo bar baz qux wiz waz woz ) ],
      people   => [ { id => 'tom',   name => 'Tom' },
                    { id => 'dick',  name => 'Richard' },
                    { id => 'larry', name => 'Larry' },
                    ],
      primes    => [ 13, 11, 17, 19, 2, 3, 5, 7 ],
      phones    => { 3141 => 'Leon', 5131 => 'Andy', 4131 => 'Simon' },
      groceries => { 'Flour' => 3, 'Milk' => 1, 'Peanut Butter' => 21 },
      names     => [ map { My::Object->new($_) }
                     qw( Tom Dick Larry ) ],
      numbers   => [ map { My::Object->new($_) }
                     qw( 1 02 10 12 021 ) ],
      duplicates => [ 1, 1, 2, 2, 3, 3, 4, 4, 5, 5],
  };
  
  my $tt = Template->new();
  my $tc = $tt->context();
  
  # define vmethods using define_vmethod() interface.
  $tc->define_vmethod(list   => oddnos => \&odd);
  $tc->define_vmethod(array  => jumblate => \&jumble);
  
  test_expect(\*DATA, undef, $params);
  
  __DATA__
  
  #------------------------------------------------------------------------
  # list virtual methods
  #------------------------------------------------------------------------
  
  -- test --
  [% metavars.first %]
  -- expect --
  foo
  
  -- test --
  [% metavars.last %]
  -- expect --
  woz
  
  -- test --
  [% metavars.size %]
  -- expect --
  7
  
  -- test --
  [% empty = [ ];
     empty.size 
  %]
  -- expect --
  0
  
  -- test --
  [% metavars.max %]
  -- expect --
  6
  
  -- test --
  [% metavars.join %]
  -- expect --
  foo bar baz qux wiz waz woz
  
  -- test --
  [% metavars.join(', ') %]
  -- expect --
  foo, bar, baz, qux, wiz, waz, woz
  
  -- test --
  [% metavars.sort.join(', ') %]
  -- expect --
  bar, baz, foo, qux, waz, wiz, woz
  
  -- test --
  [% metavars.defined ? 'list def ok' : 'list def not ok' %]
  [% metavars.defined(2) ? 'list two ok' : 'list two not ok' %]
  [% metavars.defined(7) ? 'list seven not ok' : 'list seven ok' %]
  -- expect --
  list def ok
  list two ok
  list seven ok
  
  -- test --
  [% FOREACH person = people.sort('id') -%]
  [% person.name +%]
  [% END %]
  -- expect --
  Richard
  Larry
  Tom
  
  -- test --
  [% FOREACH obj = names.sort('name') -%]
  [% obj.name +%]
  [% END %]
  -- expect --
  Dick
  Larry
  Tom
  
  -- test --
  [% FOREACH obj = numbers.sort('name') -%]
  [% obj.name +%]
  [% END %]
  -- expect --
  02
  021
  1
  10
  12
  
  -- test --
  [% FOREACH obj = numbers.nsort('name') -%]
  [% obj.name +%]
  [% END %]
  -- expect --
  1
  02
  10
  12
  021
  
  -- test --
  [% FOREACH person = people.sort('name') -%]
  [% person.name +%]
  [% END %]
  -- expect --
  Larry
  Richard
  Tom
  
  -- test --
  [% folk = [] -%]
  [% folk.push("<a href=\"${person.id}.html\">$person.name</a>")
      FOREACH person = people.sort('id') -%]
  [% folk.join(",\n") %]
  -- expect --
  <a href="dick.html">Richard</a>,
  <a href="larry.html">Larry</a>,
  <a href="tom.html">Tom</a>
  
  -- test --
  [% primes.sort.join(', ') %]
  -- expect --
  11, 13, 17, 19, 2, 3, 5, 7
  
  -- test --
  [% primes.nsort.join(', ') %]
  -- expect --
  2, 3, 5, 7, 11, 13, 17, 19
  
  -- test --
  [% duplicates.unique.join(', ') %]
  --expect --
  1, 2, 3, 4, 5
  
  -- test --
  [% duplicates.unique.join(', ') %]
  -- expect --
  1, 2, 3, 4, 5
  
  
  
  -- test --
  -- name list import one --
  [% list_one = [ 1 2 3 ];
     list_two = [ 4 5 6 ];
     list_one.import(list_two).join(', ') %]
  -- expect --
  1, 2, 3, 4, 5, 6
  
  -- test --
  -- name list import two --
  [% list_one = [ 1 2 3 ];
     list_two = [ 4 5 6 ];
     list_three = [ 7 8 9 0 ];
     list_one.import(list_two, list_three).join(', ') %]
  -- expect --
  1, 2, 3, 4, 5, 6, 7, 8, 9, 0
  
  
  -- test --
  -- name list merge one --
  [% list_one = [ 1 2 3 ];
     list_two = [ 4 5 6 ];
     "'$l' " FOREACH l = list_one.merge(list_two) %]
  -- expect --
  '1' '2' '3' '4' '5' '6' 
  
  -- test --
  -- name list merge two --
  [% list_one = [ 1 2 3 ];
     list_two = [ 4 5 6 ];
     list_three = [ 7 8 9 0 ];
     "'$l' " FOREACH l = list_one.merge(list_two, list_three) %]
  -- expect --
  '1' '2' '3' '4' '5' '6' '7' '8' '9' '0' 
  
  -- test --
  [% list_one = [ 1 2 3 4 5 ] -%]
  a: [% list_one.splice.join(', ') %]
  b: [% list_one.size ? list_one.join(', ') : 'empty list' %]
  -- expect --
  a: 1, 2, 3, 4, 5
  b: empty list
  
  -- test --
  [% list_one = [ 'a' 'b' 'c' 'd' 'e' ] -%]
  a: [% list_one.splice(3).join(', ') %]
  b: [% list_one.join(', ') %]
  -- expect --
  a: d, e
  b: a, b, c
  
  -- test --
  [% list_one = [ 'a' 'b' 'c' 'd' 'e' ] -%]
  c: [% list_one.splice(3, 1).join(', ') %]
  d: [% list_one.join(', ') %]
  -- expect --
  c: d
  d: a, b, c, e
  
  -- test --
  [% list_one = [ 'a' 'b' 'c' 'd' 'e' ] -%]
  c: [% list_one.splice(3, 1, 'foo').join(', ') %]
  d: [% list_one.join(', ') %]
  e: [% list_one.splice(0, 1, 'ping', 'pong').join(', ') %]
  f: [% list_one.join(', ') %]
  g: [% list_one.splice(-1, 1, ['wibble', 'wobble']).join(', ') %]
  h: [% list_one.join(', ') %]
  -- expect --
  c: d
  d: a, b, c, foo, e
  e: a
  f: ping, pong, b, c, foo, e
  g: e
  h: ping, pong, b, c, foo, wibble, wobble
  
  -- test --
  -- name scrabble --
  [% play_game = [ 'play', 'scrabble' ];
     ping_pong = [ 'ping', 'pong' ] -%]
  a: [% play_game.splice(1, 1, ping_pong).join %]
  b: [% play_game.join %]
  -- expect --
  a: scrabble
  b: play ping pong
  
  
  -- test --
  -- name first --
  [% primes = [ 2, 3, 5, 7, 11, 13 ] -%]
  [% primes.first +%]
  [% primes.first(3).join(', ') %]
  -- expect --
  2
  2, 3, 5
  
  -- test --
  -- name first --
  [% primes = [ 2, 3, 5, 7, 11, 13 ] -%]
  [% primes.last +%]
  [% primes.last(3).join(', ') %]
  -- expect --
  13
  7, 11, 13
  
  
  -- test --
  -- name slice --
  [% primes = [ 2, 3, 5, 7, 11, 13 ] -%]
  [% primes.slice(0, 2).join(', ') +%]
  [% primes.slice(-2, -1).join(', ') +%]
  [% primes.slice(3).join(', ') +%]
  [% primes.slice.join(', ') +%]
  --expect --
  2, 3, 5
  11, 13
  7, 11, 13
  2, 3, 5, 7, 11, 13
  
  
  -- test --
  -- name list.hash --
  [% items = ['zero', 'one', 'two', 'three'];
     hash = items.hash(0);
     "$key = $value\n" FOREACH hash.pairs;
  -%]
  -- expect --
  0 = zero
  1 = one
  2 = two
  3 = three
  
  -- test --
  -- name list.hash(10) --
  [% items = ['zero', 'one', 'two', 'three'];
     hash = items.hash(10);
     "$key = $value\n" FOREACH hash.pairs;
  -%]
  -- expect --
  10 = zero
  11 = one
  12 = two
  13 = three
  
  
  -- test --
  -- name list.hash --
  [% items = ['zero', 'one', 'two', 'three'];
     hash = items.hash;
     "$key = $value\n" FOREACH hash.pairs;
  -%]
  -- expect --
  two = three
  zero = one
  
  
  
  #------------------------------------------------------------------------
  # USER DEFINED LIST OPS
  #------------------------------------------------------------------------
  
  -- test --
  [% items = [0..6] -%]
  [% items.jumble.join(', ') %]
  [% items.jumble(3).join(', ') %]
  -- expect --
  1, 2, 3, 4, 5, 6, 0
  4, 5, 6, 0, 1, 2, 3
  
  -- test --
  -- name jumblate method --
  [% items = [0..6] -%]
  [% items.jumblate.join(', ') %]
  [% items.jumblate(3).join(', ') %]
  -- expect --
  1, 2, 3, 4, 5, 6, 0
  4, 5, 6, 0, 1, 2, 3
  
  -- test -- 
  [% primes.sum %]
  -- expect --
  77
  
  -- test --
  [% primes.odd.nsort.join(', ') %]
  -- expect --
  3, 5, 7, 11, 13, 17, 19
  
  -- test --
  -- name oddnos --
  [% primes.oddnos.nsort.join(', ') %]
  -- expect --
  3, 5, 7, 11, 13, 17, 19
  
  -- test --
  [% FOREACH n = phones.sort -%]
  [% phones.$n %] is [% n %],
  [% END %]
  -- expect --
  Andy is 5131,
  Leon is 3141,
  Simon is 4131,
  
  -- test --
  -- name groceries --
  [% FOREACH n = groceries.nsort.reverse -%]
  I want [% groceries.$n %] kilos of [% n %],
  [% END %]
  -- expect --
  I want 21 kilos of Peanut Butter,
  I want 3 kilos of Flour,
  I want 1 kilos of Milk,
  
  
  
  -- test --
  [% hash = { }
     list = [ hash ]
     list.last.message = 'Hello World';
     "message: $list.last.message\n"
  -%]
  
  -- expect --
  message: Hello World
  
  
  
  
  
  
  
  1.1                  Template2/t/vmethods/replace.t
  
  Index: replace.t
  ===================================================================
  #============================================================= -*-perl-*-
  #
  # t/vmethods/replace.t
  #
  # Testing the 'replace' scalar virtual method, and in particular the
  # use of backreferences.
  #
  # Written by Andy Wardley <abw@cpan.org> and Sergey Martynoff 
  # <sergey@martynoff.info>
  #
  # This is free software; you can redistribute it and/or modify it
  # under the same terms as Perl itself.
  #
  # $Id: replace.t,v 1.1 2006/02/02 11:35:07 abw Exp $
  #
  #========================================================================
  
  use strict;
  use lib qw( ./lib ../lib ../../lib );
  use Template::Test;
  use Template::Config;
  use Template::Stash;
  $^W = 1;
  
  # make sure we're using the Perl stash
  $Template::Config::STASH = 'Template::Stash';
  
  $Template::Stash::SCALAR_OPS->{ new_replace } = \&vmethod_replace;
  
  sub vmethod_replace {
      my ($text, $pattern, $replace, $global) = @_;
      $text    = '' unless defined $text;
      $pattern = '' unless defined $pattern;
      $replace = '' unless defined $replace;
      $global  = 1  unless defined $global;
  
      my $expand = sub {
          my ($chunk, $start, $end) = @_;
          $chunk =~ s{ \\(\\|\$) | \$ (\d+) }{
              $1 ? $1
                 : ($2 > $#$start || $2 == 0) ? '' 
                 : substr($text, $start->[$2], $end->[$2] - $start->[$2]);
          }exg;
          $chunk;
      };
          
      if ($global) {
          $text =~ s{$pattern}{ &$expand($replace, [@-], [@+]) }eg;
      } 
      else {
          $text =~ s{$pattern}{ &$expand($replace, , [@-], [@+]) }e;
      }
      return $text;
  }
  
  
  
  sub vmethod_replace2 {
      my ($str, $pat, $replace, $global) = @_;
      $str     = '' if ! defined $str;
      $pat     = '' if ! defined $pat;
      $replace = '' if ! defined $replace;
      $global  = 1  if ! defined $global;
  
      if ($global) {
          $str =~ s{$pat}{
              my @start = @-;
              my @end   = @+;
              my $copy  = $replace;
              $copy =~ s{ (?<!\\) \$ (\d+) }{
                  ($1 > $#start || $1 == 0) ? '' 
                      : substr($str, $start[$1], $end[$1] - $start[$1]);
              }exg;
              $copy;
          }eg;
      } 
      else {
          $str =~ s{$pat} {
              my @start = @-;
              my @end   = @+;
              my $copy  = $replace;
              $copy =~ s{ (?<!\\) \$ (\d+) }{
                  ($1 > $#start || $1 == 0) ? '' 
                      : substr($str, $start[$1], $end[$1] - $start[$1]);
              }exg;
              $copy;
          }e;
      }
      return $str;
  }
  
  
  test_expect(\*DATA);
  
  __DATA__
  
  -- test --
  -- name: two backrefs --
  [% text = 'The cat sat on the mat';
     text.replace( '(\w+) sat on the (\w+)',
                   'dirty $1 shat on the filthy $2' )
  %]
  -- expect --
  The dirty cat shat on the filthy mat
  
  
  # test more than 9 captures to make sure $10, $11, etc., work ok
  -- test --
  -- name: ten+ backrefs --
  [% text = 'one two three four five six seven eight nine ten eleven twelve thirteen';
     text.replace(
        '(\w+) (\w+) (\w+) (\w+) (\w+) (\w+) (\w+) (\w+) (\w+) (\w+) (\w+) (\w+)',
        '[$12-$11-$10-$9-$8-$7-$6-$5-$4-$3-$2-$1]'
     )
  %]
  -- expect --
  [twelve-eleven-ten-nine-eight-seven-six-five-four-three-two-one] thirteen
  
  
  -- test --
  -- name: repeat backrefs --
  [% text = 'one two three four five six seven eight nine ten eleven twelve thirteen';
     text.replace(
        '(\w+) ',
        '[$1]-'
     )
  %]
  -- expect --
  [one]-[two]-[three]-[four]-[five]-[six]-[seven]-[eight]-[nine]-[ten]-[eleven]-[twelve]-thirteen
  
  -- test --
  -- name: one backref --
  [% var = 'foo'; var.replace('f(o+)$', 'b$1') %]
  -- expect --
  boo
  
  -- test --
  -- name: three backrefs --
  [% var = 'foo|bar/baz'; var.replace('(fo+)\|(bar)(.*)$', '[ $1, $2, $3 ]') %]
  -- expect --
  [ foo, bar, /baz ]
  
  
  #------------------------------------------------------------------------
  # tests based on Sergey's test script: http://martynoff.info/tt2/
  #------------------------------------------------------------------------
  
  -- test --
  [% text = 'foo bar';
     text.replace('foo', 'bar')
  %]
  -- expect --
  bar bar
  
  
  -- test --
  [% text = 'foo bar';
     text.replace('(f)(o+)', '$2$1')
  %]
  -- expect --
  oof bar
  
  -- test --
  [% text = 'foo bar foo';
     text.replace('(?i)FOO', 'zoo')
  %]
  -- expect --
  zoo bar zoo
  
  
  #------------------------------------------------------------------------
  # references to $n vars that don't exists are ignored
  #------------------------------------------------------------------------
  
  -- test --
  [% text = 'foo bar';
     text.replace('(f)(o+)', '$20$1')
  %]
  -- expect --
  f bar
  
  -- test --
  [% text = 'foo bar';
     text.replace('(f)(o+)', '$2$10')
  %]
  -- expect --
  oo bar
  
  -- test --
  [% text = 'foo fgoo foooo bar';
     text.replace('((?:f([^o]*)(o+)\s)+)', '1=$1;2=$2;3=$3;')
  %]
  -- expect --
  1=foo fgoo foooo ;2=;3=oooo;bar
  
  
  #------------------------------------------------------------------------
  # $n in source string should not be interpolated
  #------------------------------------------------------------------------
  
  -- test --
  [% text = 'foo $1 bar';
     text.replace('(foo)(.*)(bar)', '$1$2$3')
  %]
  -- expect --
  foo $1 bar
  
  -- test --
  [% text = 'foo $1 bar';
     text.replace('(foo)(.*)(bar)', '$3$2$1')
  %]
  -- expect --
  bar $1 foo
  
  -- test --
  [% text = 'foo $200bar foobar';
     text.replace('(f)(o+)', 'zoo')
  %]
  -- expect --
  zoo $200bar zoobar
  
  
  #------------------------------------------------------------------------
  # escaped \$ in replacement string
  #------------------------------------------------------------------------
  
  -- test --
  -- name: escape dollar --
  [% text = 'foo bar';
     text.replace('(f)(o+)', '\\$2$1')
  %]
  -- expect --
  $2f bar
  
  
  -- test --
  -- name: escape backslash --
  [% text = 'foo bar';
     text.replace('(f)(o+)', 'x$1\\\\y$2'); # this is 'x$1\\y$2'
  %]
  -- expect --
  xf\yoo bar
  
  -- test --
  -- name: backslash again --
  [% text = 'foo bar';
     text.replace('(f)(o+)', '$2\\\\$1');   # this is '$2\\$1'
  %]
  -- expect --
  oo\f bar
  
  -- test --
  -- name: escape all over --
  [% text = 'foo bar';
     text.replace('(f)(o+)', '$2\\\\\\$1'); # this is '$2\\\$')
  %]
  -- expect --
  oo\$1 bar
  
  
  -- test --
  [% text = 'foo bar foobar';
     text.replace('(o)|([ar])', '$2!')
  %]
  -- expect --
  f!! ba!r! f!!ba!r!
  
  
  
  
  
  1.1                  Template2/t/vmethods/text.t
  
  Index: text.t
  ===================================================================
  #============================================================= -*-perl-*-
  #
  # t/vmethods/text.t
  #
  # Testing scalar (text) virtual variable methods.
  #
  # Written by Andy Wardley <abw@cpan.org>
  #
  # Copyright (C) 1996-2006 Andy Wardley.  All Rights Reserved.
  #
  # This is free software; you can redistribute it and/or modify it
  # under the same terms as Perl itself.
  #
  # $Id: text.t,v 1.1 2006/02/02 11:35:07 abw Exp $
  #
  #========================================================================
  
  use strict;
  use warnings;
  use lib qw( ./lib ../lib ../../lib );
  use Template::Test;
  
  # make sure we're using the Perl stash
  $Template::Config::STASH = 'Template::Stash';
  
  # define a new text method
  $Template::Stash::SCALAR_OPS->{ commify } = sub {
      local $_  = shift;
      my $c = shift || ",";
      my $n = int(shift || 3);
      return $_ if $n<1;
      1 while s/^([-+]?\d+)(\d{$n})/$1$c$2/;
      return $_;
  };
  
  
  my $tt = Template->new();
  my $tc = $tt->context();
  
  # define vmethods using define_vmethod() interface.
  $tc->define_vmethod( item => 
                       commas => 
                       $Template::Stash::SCALAR_OPS->{ commify } );
  
  my $params = {
      undef    => undef,
      zero     => 0,
      one      => 1,
      animal   => 'cat',
      string   => 'The cat sat on the mat',
      spaced   => '  The dog sat on the log',
  };
  
  test_expect(\*DATA, undef, $params);
  
  __DATA__
  
  #------------------------------------------------------------------------
  # defined
  #------------------------------------------------------------------------
  
  -- test --
  [% notdef.defined ? 'def' : 'undef' %]
  -- expect --
  undef
  
  -- test --
  [% undef.defined ? 'def' : 'undef' %]
  -- expect --
  undef
  
  -- test --
  [% zero.defined ? 'def' : 'undef' %]
  -- expect --
  def
  
  -- test --
  [% one.defined ? 'def' : 'undef' %]
  -- expect --
  def
  
  -- test --
  [% string.length %]
  -- expect --
  22
  
  -- test --
  [% string.sort.join %]
  -- expect --
  The cat sat on the mat
  
  -- test --
  [% string.split.join('_') %]
  -- expect --
  The_cat_sat_on_the_mat
  -- test --
  
  -- test --
  [% string.split(' ', 3).join('_') %]
  -- expect --
  The_cat_sat on the mat
  
  -- test --
  [% spaced.split.join('_') %]
  -- expect --
  The_dog_sat_on_the_log
  
  -- test --
  [% spaced.split(' ').join('_') %]
  -- expect --
  __The_dog_sat_on_the_log
  
  -- test --
  -- name: text.list --
  [% string.list.join %]
  -- expect --
  The cat sat on the mat
  
  -- test --
  -- name: text.hash --
  [% string.hash.value %]
  -- expect --
  The cat sat on the mat
  
  -- test --
  -- name: text.size --
  [% string.size %]
  -- expect --
  1
  
  -- test --
  -- name: text.repeat --
  [% animal.repeat(3) %]
  -- expect --
  catcatcat
  
  -- test --
  -- name: text.search --
  [% animal.search('at$') ? "found 'at\$'" : "didn't find 'at\$'" %]
  -- expect --
  found 'at$'
  
  -- test --
  -- name: text.search --
  [% animal.search('^at') ? "found '^at'" : "didn't find '^at'" %]
  -- expect --
  didn't find '^at'
  
  -- test --
  -- name: text.match an --
  [% text = 'bandanna';
     text.match('an') ? 'match' : 'no match'
  %]
  -- expect --
  match
  
  -- test --
  -- name: text.match on --
  [% text = 'bandanna';
     text.match('on') ? 'match' : 'no match'
  %]
  -- expect --
  no match
  
  -- test --
  -- name: text.match global an --
  [% text = 'bandanna';
     text.match('an', 1).size %] matches
  -- expect --
  2 matches
  
  -- test --
  -- name: text.match global an --
  [% text = 'bandanna' -%]
  matches are [% text.match('an+', 1).join(', ') %]
  -- expect --
  matches are an, ann
  
  -- test --
  -- name: text.match global on --
  [% text = 'bandanna';
     text.match('on+', 1) ? 'match' : 'no match'
  %]
  -- expect --
  no match
  
  -- test --
  -- name: text substr method --
  [% text = 'Hello World' -%]
  a: [% text.substr(6) %]!
  b: [% text.substr(0, 5) %]!
  c: [% text.substr(0, 5, 'Goodbye') %]!
  d: [% text %]!
  -- expect --
  a: World!
  b: Hello!
  c: Goodbye World!
  d: Hello World!
  
  -- test --
  -- name: another text substr method --
  [% text = 'foo bar baz wiz waz woz' -%]
  a: [% text.substr(4, 3) %]
  b: [% text.substr(12) %]
  c: [% text.substr(0, 11, 'FOO') %]
  d: [% text %]
  -- expect --
  a: bar
  b: wiz waz woz
  c: FOO wiz waz woz
  d: foo bar baz wiz waz woz
  
  
  -- test --
  -- name: text.remove --
  [% text = 'hello world!';
     text.remove('\s+world')
  %]
  -- expect --
  hello!
  
  
  
  -- test --
  -- name chunk left --
  [% string = 'TheCatSatTheMat' -%]
  [% string.chunk(3).join(', ') %]
  -- expect --
  The, Cat, Sat, The, Mat
  
  -- test --
  -- name chunk leftover --
  [% string = 'TheCatSatonTheMat' -%]
  [% string.chunk(3).join(', ') %]
  -- expect --
  The, Cat, Sat, onT, heM, at
  
  -- test --
  -- name chunk right --
  [% string = 'TheCatSatTheMat' -%]
  [% string.chunk(-3).join(', ') %]
  -- expect --
  The, Cat, Sat, The, Mat
  
  -- test --
  -- name chunk rightover --
  [% string = 'TheCatSatonTheMat' -%]
  [% string.chunk(-3).join(', ') %]
  -- expect --
  Th, eCa, tSa, ton, The, Mat
  
  -- test --
  -- name chunk ccard  --
  [% ccard_no = "1234567824683579";
     ccard_no.chunk(4).join
  %]
  -- expect --
  1234 5678 2468 3579
  
  
  -- test --
  [% string = 'foo' -%]
  [% string.repeat(3) %]
  -- expect --
  foofoofoo
  
  -- test --
  [% string1 = 'foobarfoobarfoo'
     string2 = 'foobazfoobazfoo'
  -%]
  [% string1.search('bar') ? 'ok' : 'not ok' %]
  [% string2.search('bar') ? 'not ok' : 'ok' %]
  [% string1.replace('bar', 'baz') %]
  [% string2.replace('baz', 'qux') %]
  -- expect --
  ok
  ok
  foobazfoobazfoo
  fooquxfooquxfoo
  
  -- test --
  [% string1 = 'foobarfoobarfoo'
     string2 = 'foobazfoobazfoo'
  -%]
  [% string1.match('bar') ? 'ok' : 'not ok' %]
  [% string2.match('bar') ? 'not ok' : 'ok' %]
  -- expect --
  ok
  ok
  
  -- test --
  [% string = 'foo     bar   ^%$ baz' -%]
  [% string.replace('\W+', '_') %]
  -- expect --
  foo_bar_baz
  
  -- test --
  [% var = 'value99' ;
     var.replace('value', '')
  %]
  -- expect --
  99
  
  -- test --
  [% bob = "0" -%]
  bob: [% bob.replace('0','') %].
  -- expect --
  bob: .
  
  -- test --
  [% string = 'The cat sat on the mat';
     match  = string.match('The (\w+) (\w+) on the (\w+)');
  -%]
  [% match.0 %].[% match.1 %]([% match.2 %])
  -- expect --
  cat.sat(mat)
  
  -- test --
  [% string = 'The cat sat on the mat' -%]
  [% IF (match  = string.match('The (\w+) sat on the (\w+)')) -%]
  matched animal: [% match.0 %]  place: [% match.1 %]
  [% ELSE -%]
  no match
  [% END -%]
  [% IF (match  = string.match('The (\w+) shat on the (\w+)')) -%]
  matched animal: [% match.0 %]  place: [% match.1 %]
  [% ELSE -%]
  no match
  [% END -%]
  -- expect --
  matched animal: cat  place: mat
  no match
  
  
  -- test --
  [% big_num = "1234567890"; big_num.commify %]
  -- expect --
  1,234,567,890
  
  -- test --
  [% big_num = "1234567890"; big_num.commify(":", 2) %]
  -- expect --
  12:34:56:78:90
  
  -- test --
  [% big_num = "1234567812345678"; big_num.commify(" ", 4) %]
  -- expect --
  1234 5678 1234 5678
  
  -- test --
  [% big_num = "hello world"; big_num.commify %]
  -- expect --
  hello world
  
  -- test --
  [% big_num = "1234567890"; big_num.commas %]
  -- expect --
  1,234,567,890