Kato Atsushi
ktats****@users*****
2006年 10月 22日 (日) 05:18:38 JST
Index: docs/modules/Test-Base-0.52/lib/Test/Base.pod diff -u /dev/null docs/modules/Test-Base-0.52/lib/Test/Base.pod:1.1 --- /dev/null Sun Oct 22 05:18:37 2006 +++ docs/modules/Test-Base-0.52/lib/Test/Base.pod Sun Oct 22 05:18:37 2006 @@ -0,0 +1,964 @@ +=head1 åå + +Test::Base - ãã¼ã¿ããªãã³ã®ãã¹ããã¬ã¼ã ã¯ã¼ã¯ + +=head1 æ¦è¦ + +A new test module: + +æ°ãããã¹ãã¢ã¸ã¥ã¼ã«: + + # lib/MyProject/Test.pm + package MyProject::Test; + use Test::Base -Base; + + use MyProject; + + package MyProject::Test::Filter; + use Test::Base::Filter -base; + + sub my_filter { + return MyProject->do_something(shift); + } + +A sample test: + +ãã¹ãã®ä¾: + + # t/sample.t + use MyProject::Test; + + plan tests => 1 * blocks; + + run_is input => 'expected'; + + sub local_filter { + s/my/your/; + } + + __END__ + + === Test one (the name of the test) + --- input my_filter local_filter + my + input + lines + --- expected + expected + output + + === Test two + This is an optional description + of this particular test. + --- input my_filter + other + input + lines + --- expected + other expected + output + +=head1 説æ + +Testing is usually the ugly part of Perl module authoring. Perl gives +you a standard way to run tests with Test::Harness, and basic testing +primitives with Test::More. After that you are pretty much on your own +to develop a testing framework and philosophy. Test::More encourages +you to make your own framework by subclassing Test::Builder, but that is +not trivial. + +Perlã¢ã¸ã¥ã¼ã«ãæ¸ãä¸ã§ãéãã®ã¯ããã¦ããã¹ãã®ã¨ããã§ããPerlã«ã¯ +æ¨æºã®ããããã¨ãã¦ãTest::Harnesãããã¾ããåºæ¬çã§åå§çãªãã¹ã㯠+Test::Moreã§è¡ãã¾ãããã®å¾ã§ããã¹ããã¬ã¼ã ã¯ã¼ã¯ã¨å²å¦ãéçºããããã« +ããªãã¯ã»ã¨ãã©ä¸äººã§ãã¾ã(訳註:è¬)ãTest::Moreã¯Test::Builderã +ãµãã¯ã©ã¹ã«ãã¦ãèªåèªèº«ã®ãã¬ã¼ã ã¯ã¼ã¯ãä½ããã¨ãæ¨å¥¨ãã¦ãã¾ãã +ã§ãããããã¯ç°¡åãªãã¨ã§ã¯ããã¾ããã + +Test::Base gives you a way to write your own test framework base +class that I<is> trivial. In fact it is as simple as two lines: + +Test::Base ã使ãã¨ãèªåç¨ã®åãã«ãããªããã¹ããã¬ã¼ã ã¯ã¼ã¯ã® +ãã¼ã¹ã¯ã©ã¹ãæ¸ããã¨ãã§ãã¾ããå®éã以ä¸ã®2è¡ã§ã§ãããããç°¡åã§ã: + + package MyTestFramework; + use Test::Base -Base; + +A module called C<MyTestFramework.pm> containing those two lines, will +give all the power of Test::More and all the power of Test::Base to +every test file that uses it. As you build up the capabilities of +C<MyTestFramework>, your tests will have all of that power as well. + +ãã®2è¡ãããªãC<MyTestFramework>ã¨å¼ã°ããã¢ã¸ã¥ã¼ã«ã¯ã +ããã使ãå ¨ã¦ã®ãã¹ããã¡ã¤ã«ã«ãTest::Moreã®å ¨ã¦ã®åã¨ã +Test::Baseã®å ¨ã¦ã®åãä¸ãã¾ããC<MyTestFramework>ã®è½åãé«ããã«ã¤ãã +ããªãã®ãã¹ããåæ§ã«ãã®åã®å ¨ã¦ãæã¤ã§ãããã + +C<MyTestFramework> becomes a place for you to put all of your reusable +testing bits. As you write tests, you will see patterns and duplication, +and you can "upstream" them into C<MyTestFramework>. Of course, you +don't have to subclass Test::Base at all. You can use it directly in +many applications, including everywhere you would use Test::More. + +C<MyTestFramework>ã¯åå©ç¨å¯è½ãªãã¹ãã®å ¨ã¦ãç½®ãå ´æã«ãªãã¾ãã +ãã¹ããæ¸ãã«ã¤ãããã¿ã¼ã³ãéè¤ãè¦ããã¦ãããããC<MyTestFramework>ã« +"ä¸æµ"ã«åºæ¥ãã§ãããããã¡ãããTest::Baseããµãã¯ã©ã¹ã«ããªããã° +ãããªãããã§ã¯å ¨ç¶ããã¾ãããå¤ãã®ã¢ããªã±ã¼ã·ã§ã³ã§ãTest::Baseã +ç´æ¥ä½¿ããã¨ãåºæ¥ã¾ãããTest::Moreã使ã£ã¦ããã©ãã«ã§ãTest::Baseã +使ããã¨ãåºæ¥ã¾ãã + +Test::Base concentrates on offering reusable data driven patterns, so +that you can write tests with a minimum of code. At the heart of all +testing you have inputs, processes and expected outputs. Test::Base +provides some clean ways for you to express your input and expected +output data, so you can spend your time focusing on that rather than +your code scaffolding. + +Test::Baseã¯åå©ç¨å¯è½ãªãã¼ã¿ããªãã³ãªãã¿ã¼ã³ãæä¾ããã®ã« +éä¸ãã¦ãã¾ãããã®ãããæå°éã®ã³ã¼ãã§ãã¹ããæ¸ãã¾ãã +å ¨ã¦ã®ãã¹ãã®ä¸å¿ã«ãå ¥åãå¦çãæå¾ ãããåºåãããã¾ãã +Test::Baseã«ã¯ãå ¥åã¨æå¾ ãããå¤ã表ãã®ã«ç°¡åãªæ¹æ³ãããã¾ãã +ãã®ãããã³ã¼ãã®è¶³å ´ä½ãã§ã¯ãªãã¦ãä¸å¿ã®ãã¨ã«éä¸ã§ãã¾ãã + +=head1 ã¨ã¯ã¹ãã¼ããããé¢æ° + +Test::Base extends Test::More and exports all of its functions. So you +can basically write your tests the same as Test::More. Test::Base +also exports many functions of its own: + +Test::Baseã¯Test::Moreãç¶æ¿ãã¦ãããTest::Moreã®å ¨ã¦ã®é¢æ°ã +ã¨ã¯ã¹ãã¼ããã¦ãã¾ãããã®ãããåºæ¬çã«ãTest::Moreã¨åãããã« +ãã¹ããæ¸ããã¨ãåºæ¥ã¾ããTest::Baseãã¾ããããèªèº«ã®å¤ãã®é¢æ°ã +ã¨ã¯ã¹ãã¼ããã¦ãã¾ãã + +=head2 is(actual, expected, [test-name]) + +This is the equivalent of Test::More's C<is> function with one +interesting twist. If your actual and expected results differ and the +output is multi-line, this function will show you a unified diff format +of output. Consider the benefit when looking for the one character that +is different in hundreds of lines of output! + +Test::Moreã®C<is>é¢æ°ã¨åçã§ãããä¸ã²ããå ãã¦ãã¾ãã +å®éã¨æå¾ ããçµæãéã£ã¦ãããåºåãè¤æ°è¡ã«ãããå ´åã +ãã®é¢æ°ã¯ãåºåã unified diffãã©ã¼ããã(訳註: diff -u)ã§è¡¨ç¤ºãã¾ãã +ä¸æåéãã ããªã®ã«ãæ°ç¾è¡ã®åºåãåºã¦ãå¬ãããªãã§ããï¼ + +Diff output requires the optional C<Text::Diff> CPAN module. If you +don't have this module, the C<is()> function will simply give you normal +Test::More output. To disable diffing altogether, set the +C<TEST_SHOW_NO_DIFFS> environment variable (or C<$ENV{TEST_SHOW_NO_DIFFS}>) +to a true value. You can also call the C<no_diff> function as a shortcut. + +Diffåºåã¯ãªãã·ã§ã³ã§ãCPANã¢ã¸ã¥ã¼ã«ã®C<Text::Diff>ãå¿ è¦ã§ãã +ãã®ã¢ã¸ã¥ã¼ã«ããªããã°ãC<is()>é¢æ°ã¯åç´ã«ãé常ã®Test::Moreã® +åºåã表示ãã¾ããdiffãå®å ¨ã«ç¡å¹ã«ããããªããC<TEST_SHOW_NO_DIFFS>ç°å¢å¤æ° +(ã¾ãã¯ã$ENV{TEST_SHOW_NO_DIFFS})ã«çã®å¤ãå ¥ãã¦ãã ããã +ã·ã§ã¼ãã«ããã¨ãã¦ãC<no_diff>é¢æ°ã使ãã¾ãã + +=head2 blocks( [data-section-name] ) + +The most important function is C<blocks>. In list context it returns a +list of C<Test::Base::Block> objects that are generated from the test +specification in the C<DATA> section of your test file. In scalar +context it returns the number of objects. This is useful to calculate +your Test::More plan. + +ä¸çªéè¦ãªé¢æ°ã¯ãC<blocks>ã§ãããªã¹ãã³ã³ããã¹ãã§ã¯ã +ãã¹ããã¡ã¤ã«ã®C<DATA>ã»ã¯ã·ã§ã³ä»¥ä¸ã«ãããã¹ãä»æ§ããçæãããã +C<Test::Base::Block>ãªãã¸ã§ã¯ãã®ãªã¹ããè¿ãã¾ãã +ã¹ã«ã©ã³ã³ããã¹ãã§ã¯ããªãã¸ã§ã¯ãã®æ°ãè¿ãã¾ãã +Test::Moreã®ãã©ã³ãæ°ããã®ã«ä¾¿å©ã§ãã + +Each Test::Base::Block object has methods that correspond to the names +of that object's data sections. There is also a C<name> and a +C<description> method for accessing those parts of the block if they +were specified. + +ããããã®Test::Base::Blockãªãã¸ã§ã¯ãã«ã¯ããªãã¸ã§ã¯ãã®ãã¼ã¿ã»ã¯ã·ã§ã³ +ã®ååã«å¯¾å¿ããã¡ã½ãããããã¾ããããããæå®ããã¦ããã°ã +ãããã¯ã®ãããã®é¨åã«ã¢ã¯ã»ã¹ããããã«ãC<name>ã¨C<description> +ã¡ã½ãããããã¾ãã + +The C<blocks> function can take an optional single argument, that +indicates to only return the blocks that contain a particular named data +section. Otherwise C<blocks> returns all blocks. + +C<blocks>é¢æ°ã¯ãªãã·ã§ã³ã§ä¸ã¤ã®å¼æ°ãåãã +ç¹å®ã®ååã®ãã¼ã¿ã»ã¯ã·ã§ã³ãå«ããããã¯ã ããè¿ãããã«åºæ¥ã¾ãã +ä¸æ¹ãC<blocks>ã¯å ¨ã¦ã®ãããã¯ãè¿ãã¾ãã + + my @all_of_my_blocks = blocks; + + my @just_the_foo_blocks = blocks('foo'); + +=head2 next_block() + +You can use the next_block function to iterate over all the blocks. + +å ¨ã¦ã®ãããã¯ãã¤ãã¬ã¼ãããnext_blocké¢æ°ãããã¾ãã + + while (my $block = next_block) { + ... + } + +It returns undef after all blocks have been iterated over. It can then +be called again to reiterate. + +å ¨ã¦ã®ãããã¯ãã¤ãã¬ã¼ããããå¾ã§ã¯ãundefãè¿ãã¾ãã +ããä¸åº¦å¼ã¹ã°ãå度ã¤ãã¬ã¼ãããã¾ãã + +=head2 first_block() + +Returns the first block or undef if there are none. It resets the iterator to +the C<next_block> function. + +æåã®ãããã¯ãè¿ãã¾ãããããã¯ããªããã°ãundefãè¿ãã¾ãã +ããã§ãC<next_block>é¢æ°ã®ã¤ãã¬ã¼ã¿ã¼ããªã»ããã§ãã¾ãã + +=head2 run(&subroutine) + +There are many ways to write your tests. You can reference each block +individually or you can loop over all the blocks and perform a common +operation. The C<run> function does the looping for you, so all you need +to do is pass it a code block to execute for each block. + +ãã¹ããæ¸ãã«ã¯ããããã®æ¹æ³ãããã¾ããå ¨ã¦ã®ãããã¯ãå¥ã ã« +åç §ãããã¨ãåºæ¥ãããå ¨ã¦ã®ãããã¯ãã«ã¼ããããã¨ãåºæ¥ããã +å ±éã®æä½ããããã¨ãåºæ¥ã¾ãããã®C<run>é¢æ°ã¯ã«ã¼ãããã®ã§ã +ããããã®ãããã¯ã«å®è¡ããã³ã¼ããããã¯ã渡ãã ãã§æ§ãã¾ããã + +The C<run> function takes a subroutine as an argument, and calls the sub +one time for each block in the specification. It passes the current +block object to the subroutine. + +C<run>é¢æ°ã¯ãå¼æ°ã¨ãã¦é¢æ°ãã¨ãã¾ããä»æ§ã«ããããããã®ãããã¯ãã¨ã« +é¢æ°ãä¸åå¼ã³ã¾ããç¾å¨ã®ãããã¯ãªãã¸ã§ã¯ãã«ãµãã«ã¼ãã³ã渡ãã¦ãã¾ãã + + run { + my $block = shift; + is(process($block->foo), $block->bar, $block->name); + }; + +=head2 run_is([data_name1, data_name2]) + +Many times you simply want to see if two data sections are equivalent in +every block, probably after having been run through one or more filters. +With the C<run_is> function, you can just pass the names of any two data +sections that exist in every block, and it will loop over every block +comparing the two sections. + +ä½åããåç´ã«å ¨ã¦ã®ãããã¯ã§ãããããä¸ã¤ããã以ä¸ã®ãã£ã«ã¿ã¼ã +éããå¾ã§ã2ã¤ã®ãã¼ã¿ã»ã¯ã·ã§ã³ãåçã§ãããã©ãããè¦ããã¨æãã¾ãã +C<run_is>é¢æ°ã§ãå ¨ã¦ã®ãããã¯ã«ããããããã2ã¤ã®ãã¼ã¿ã»ã¯ã·ã§ã³ã® +ååã渡ãã ãã§ãå ¨ã¦ã®ãããã¯ãã«ã¼ããã¦ãäºã¤ã®ã»ã¯ã·ã§ã³ãæ¯è¼ãã¾ãã + + run_is 'foo', 'bar'; + +If no data sections are given C<run_is> will try to detect them +automatically. + +ãã¼ã¿ã»ã¯ã·ã§ã³ãä¸ããªãã°ãC<run_is>ã¯èªåçã«è¦ä»ãããã¨ãã¾ãã + +NOTE: Test::Base will silently ignore any blocks that don't contain +both sections. + +注æ: Test::Baseã¯ã両æ¹ã®ã»ã¯ã·ã§ã³ãå«ãã§ããªããããã¯ã¯æé»ã« +ç¡è¦ãã¾ãã + +=head2 run_is_deeply([data_name1, data_name2]) + +Like C<run_is> but uses C<is_deeply> for complex data structure comparison. + +C<run_is>ã¨ä¼¼ã¦ãã¾ãããè¤éãªãã¼ã¿ã®æ¯è¼ã®ããã«C<is_deeply>ã使ãã¾ãã + +=head2 run_like([data_name, regexp | data_name]); + +The C<run_like> function is similar to C<run_is> except the second +argument is a regular expression. The regexp can either be a C<qr{}> +object or a data section that has been filtered into a regular +expression. + +C<run_like>é¢æ°ã¯ãC<run_is>ã«ä¼¼ã¦ãã¾ãããäºçªç®ã®å¼æ°ã +æ£è¦è¡¨ç¾ã§ããã¨ãããéãã¾ããæ£è¦è¡¨ç¾ã¯ãC<qr{}>ãªãã¸ã§ã¯ããã +æ£è¦è¡¨ç¾ã«ãã£ã«ã¿ã¼ããããã¼ã¿ã»ã¯ã·ã§ã³ã®ã©ã¡ããåãã¾ãã + + run_like 'foo', qr{<html.*}; + run_like 'foo', 'match'; + +=head2 run_unlike([data_name, regexp | data_name]); + +The C<run_unlike> function is similar to C<run_like>, except the opposite. + +C<run_unlike>é¢æ°ã¯C<run_like>ã¨ä¼¼ã¦ãã¾ããããã®å対ã§ãã + + run_unlike 'foo', qr{<html.*}; + run_unlike 'foo', 'no_match'; + +=head2 run_compare(data_name1, data_name2) + +The C<run_compare> function is like the C<run_is>, C<run_is_deeply> and +the C<run_like> functions all rolled into one. It loops over each +relevant block and determines what type of comparison to do. + +C<run_compare>é¢æ°ã¯C<run_is>ãC<run_is_deeply>ãC<run_like>ã¨ä¼¼ã¦ãã¾ããã +ãããå ¨ã¦ãä¸ã¤ã«ããé¢æ°ã§ããããããé¢é£ãããããã¯ãã«ã¼ããã +ã©ã®ç¨®é¡ã®æ¯è¼ããããã決å®ãã¾ãã + +NOTE: If you do not specify either a plan, or run any tests, the +C<run_compare> function will automatically be run. + +注æ: ãããã©ã³ãæå®ããªããã°ãå ¨ã¦ã®ãã¹ããå®è¡ãã¾ãã +C<run_compare>é¢æ°ã¯èªåçã«å®è¡ããã¾ãã + +=head2 delimiters($block_delimiter, $data_delimiter) + +Override the default delimiters of C<===> and C<--->. + +ããã©ã«ãã®ããªãã¿C<===>ã¨C<--->ããªã¼ãã¼ã©ã¤ããã¾ãã + +=head2 spec_file($file_name) + +By default, Test::Base reads its input from the DATA section. This +function tells it to get the spec from a file instead. + +ããã©ã«ãã§ã¯ãTest::Baseã¯ãDATAã»ã¯ã·ã§ã³ããå ¥åãèªã¿ã¾ãã +ãã®é¢æ°ã¯ããã®ä»£ããã«ããã¡ã¤ã«ããä»æ§ãèªãããã«ãã¾ãã + +=head2 spec_string($test_data) + +By default, Test::Base reads its input from the DATA section. This +function tells it to get the spec from a string that has been +prepared somehow. + +ããã©ã«ãã§ã¯ãTest::Baseã¯ãDATAã»ã¯ã·ã§ã³ããå ¥åãèªã¿ã¾ãã +ãã®é¢æ°ã¯ãä½ããã¦æºåãã¦ããæååããä»æ§ãå¾ãããã«ãã¾ãã + +=head2 filters( @filters_list or $filters_hashref ) + +Specify a list of additional filters to be applied to all blocks. See +L<FILTERS> below. + +å ¨ã¦ã®ãããã¯ã«é©ç¨ãããã£ã«ã¿ã¼ããªã¹ãã«è¿½å ãã¾ãã +å¾è¿°ã®L<FILTERS>ãè¦ã¦ãã ããã + +You can also specify a hash ref that maps data section names to an array +ref of filters for that data type. + +ããã·ã¥ãªãã¡ã¬ã³ã¹ã§ããã¼ã¿ã¼ã»ã¯ã·ã§ã³ã®ååã«ãã£ã«ã¿ã¼ã®é å +ãªãã¡ã¬ã³ã¹ããããã³ã°ãããã¨ãã§ãã¾ãã + + filters { + xxx => [qw(chomp lines)], + yyy => ['yaml'], + zzz => 'eval', + }; + +If a filters list has only one element, the array ref is optional. + +ãã£ã«ã¿ã¼ãªã¹ããä¸è¦ç´ ãããªããã°ãé åãªãã¡ã¬ã³ã¹ã§ãªãã¦ã +ãã¾ãã¾ããã + +=head2 filters_delay( [1 | 0] ); + +By default Test::Base::Block objects are have all their filters run +ahead of time. There are testing situations in which it is advantageous +to delay the filtering. Calling this function with no arguments or a +true value, causes the filtering to be delayed. + +ããã©ã«ãã§ã¯ãTest::Base::Blockãªãã¸ã§ã¯ãã¯ããã®ãã£ã«ã¿ã¼ã +åãã£ã¦å®è¡ãã¦ãã¾ããã·ãã¥ã¨ã¼ã·ã§ã³ã«ãã£ã¦ã¯ããã£ã«ã¿ãªã³ã°ã +é ãããã»ããé½åãè¯ããã¨ãããã¾ãããã®é¢æ°ãå¼æ°ãªãã§å¼ã¶ãã +çã®å¤ãå¼æ°ã«å¼ã¶ã¨ããã£ã«ã¿ãªã³ã°ã¯é ãã¦å®è¡ããã¾ãã + + use Test::Base; + filters_delay; + plan tests => 1 * blocks; + for my $block (blocks) { + ... + $block->run_filters; + ok($block->is_filtered); + ... + } + +In the code above, the filters are called manually, using the +C<run_filters> method of Test::Base::Block. In functions like +C<run_is>, where the tests are run automatically, filtering is delayed +until right before the test. + +ä¸è¨ã®ãããªã³ã¼ãã§ããã£ã«ã¿ã¼ã¯æåã§å¼ã°ãã¾ãã +Test::Base::Blockã®C<run_filters>ã¡ã½ããã使ãã¾ãã +C<run_is>ã®ãããªé¢æ°ã§ããã¹ããèªåçã«å®è¡ãããå ´æã§ã +ãã®ãã¹ãã®åã¾ã§ããã£ã«ã¿ãªã³ã°ãé ãããã¾ãã + +=head2 filter_arguments() + +Return the arguments after the equals sign on a filter. + +ãã£ã«ã¿ã®çå·ã®å¾ãã®å¼æ°ãè¿ãã¾ãã + + sub my_filter { + my $args = filter_arguments; + # is($args, 'whazzup'); + ... + } + + __DATA__ + === A test + --- data my_filter=whazzup + +=head2 tie_output() + +You can capture STDOUT and STDERR for operations with this function: + +ãã®é¢æ°ã§ãSTDOUTã¨STDERRããã£ããã£ã§ãã¾ã: + + my $out = ''; + tie_output(*STDOUT, $buffer); + print "Hey!\n"; + print "Che!\n"; + untie *STDOUT; + is($out, "Hey!\nChe!\n"); + +=head2 no_diff() + +Turn off diff support for is() in a test file. + +ãã¹ããã¡ã¤ã«ã®ä¸ã®is()ã®diffãµãã¼ãããªãã«ãã¾ãã + +=head2 default_object() + +Returns the default Test::Base object. This is useful if you feel +the need to do an OO operation in otherwise functional test code. See +L<OO> below. + +ããã©ã«ãã®Test::Baseãªãã¸ã§ã¯ããè¿ãã¾ãã +é¢æ°çãªãã¹ãã³ã¼ãã§ã¯ãªããOOçãªãªãã¬ã¼ã·ã§ã³ãããããªãã便å©ã§ãã +å¾è¿°ã®L<OO>ãè¦ã¦ãã ããã + +=head2 WWW() XXX() YYY() ZZZ() + +These debugging functions are exported from the Spiffy.pm module. See +L<Spiffy> for more info. + +Spiffy.pm ã¢ã¸ã¥ã¼ã«ããã¨ã¯ã¹ãã¼ãããããããã®ã³ã°é¢æ°ã§ãã +詳細ã¯L<Spiffy>ãè¦ã¦ãã ããã + +=head2 croak() carp() cluck() confess() + +You can use the functions from the Carp module without needing to import +them. Test::Base does it for you by default. + +ã¤ã³ãã¼ããããã¨ãªããCarpã¢ã¸ã¥ã¼ã«ã®é¢æ°ã使ãã¾ããTest::Base +ã¯ããã©ã«ãã§ãã¤ã³ãã¼ããã¾ãã + +=head1 ãã¹ãã®ä»æ§ + +Test::Base allows you to specify your test data in an external file, +the DATA section of your program or from a scalar variable containing +all the text input. + +Test::Baseã§ã¯ãå ¨ã¦ã®ããã¹ãå ¥åãå«ãã ãã¹ããã¼ã¿ã®æå®ãã +å¤é¨ãã¡ã¤ã«ããããã°ã©ã ã®DATAã»ã¯ã·ã§ã³å ããã¾ãã¯ã¹ã«ã©ã¼ãããã +æå®ã§ãã¾ãã + +A I<test specification> is a series of text lines. Each test (or block) +is separated by a line containing the block delimiter and an optional +test C<name>. Each block is further subdivided into named sections with +a line containing the data delimiter and the data section name. A +C<description> of the test can go on lines after the block delimiter but +before the first data section. + +I<ãã¹ãã®ä»æ§>ã¯ä¸é£ã®ããã¹ãè¡ã§ããäºãã®ãã¹ã(ããããã¯)㯠+ãããã¯ã®åºåãã¨ãªãã·ã§ã³ã®ãã¹ãã®C<name>ãå«ãè¡ã«ãã£ã¦ +åãããã¦ãã¾ããããããã®ãããã¯ã¯ãã¼ã¿ããªãã¿ã¨ãã¼ã¿ +ã»ã¯ã·ã§ã³åãå«ãã ååã¤ãã®ã»ã¯ã·ã§ã³ã«ããã«åãããã¾ãã +ãã¹ãã®C<description>ã¯ãããã¯ããªãã¿ã®å¾ã«ç¶ãããã¾ããã +æåã®ãã¼ã¿ã»ã¯ã·ã§ã³ã®åã«æ¸ãã¾ãã + +Here is the basic layout of a specification: + +ä»æ§ã®åºæ¬çãªã¬ã¤ã¢ã¦ãã§ã: + + === <block name 1> + <optional block description lines> + --- <data section name 1> <filter-1> <filter-2> <filter-n> + <test data lines> + --- <data section name 2> <filter-1> <filter-2> <filter-n> + <test data lines> + --- <data section name n> <filter-1> <filter-2> <filter-n> + <test data lines> + + === <block name 2> + <optional block description lines> + --- <data section name 1> <filter-1> <filter-2> <filter-n> + <test data lines> + --- <data section name 2> <filter-1> <filter-2> <filter-n> + <test data lines> + --- <data section name n> <filter-1> <filter-2> <filter-n> + <test data lines> + +Here is a code example: + +ã³ã¼ãã®ä¾ã§ã: + + use Test::Base; + + delimiters qw(### :::); + + # test code here + + __END__ + + ### Test One + We want to see if foo and bar + are really the same... + ::: foo + a foo line + another foo line + + ::: bar + a bar line + another bar line + + ### Test Two + + ::: foo + some foo line + some other foo line + + ::: bar + some bar line + some other bar line + + ::: baz + some baz line + some other baz line + +This example specifies two blocks. They both have foo and bar data +sections. The second block has a baz component. The block delimiter is +C<###> and the data delimiter is C<:::>. + +ãã®ä¾ã§ã¯äºã¤ã®ãããã¯ãæå®ãã¦ãã¾ãããããã¯ã«ã¯ã +fooã¨barã®ãã¼ã¿ã»ã¯ã·ã§ã³ãããã¾ããäºçªç®ã®ãããã¯ã«ã¯ã +bazã³ã³ãã¼ãã³ããããã¾ãããããã¯ã®ããªãã¿ã¯ãC<###>ã§ã +ãã¼ã¿ã®ããªãã¿ã¯C<:::>ã§ãã + +The default block delimiter is C<===> and the default data delimiter +is C<--->. + +ããã©ã«ãã®ãããã¯ããªãã¿ã¯C<===>ã§ãããã©ã«ãã®ãã¼ã¿ããªãã¿ã¯ã +C<--->ã§ãã + +There are some special data section names used for control purposes: + +ãã¼ã¿ã»ã¯ã·ã§ã³ã®ååã«ã¯ãç¹å¥ãªååãããããã¹ããã³ã³ããã¼ã«ããããã«ä½¿ãã¾ã: + + --- SKIP + --- ONLY + --- LAST + +A block with a SKIP section causes that test to be ignored. This is +useful to disable a test temporarily. + +SKIPã¤ããã®ãããã¯ã»ã¯ã·ã§ã³ã¯ãã¹ããç¡è¦ãã¾ããä¸æçã«ãã¹ãã +ç¡åã«ããã®ã«ä¾¿å©ã§ãã + +A block with an ONLY section causes only that block to be used. This is +useful when you are concentrating on getting a single test to pass. If +there is more than one block with ONLY, the first one will be chosen. + +ONLYããããã¯ã«ä»ããã¨ããã®ãããã¯ã ãã使ããã¾ãã +ä¸ã¤ã®ãã¹ãããã¹ããã®ã«éä¸ãããæã«ä¾¿å©ã§ãã +ä¸ã¤ä»¥ä¸ã®ONLYãããã¯ãããå ´åãæåã®ãã®ãé¸ã°ãã¾ãã + +A block with a LAST section makes that block the last one in the +specification. All following blocks will be ignored. + +LASTã®ã¤ãããããã¯ã»ã¯ã·ã§ã³ã¯ããã®ãããã¯ãä»æ§ã®æå¾ã®ãã®ã«ãã¾ãã +å¾ã«ç¶ããããã¯ã¯ç¡è¦ããã¾ãã + +=head1 FILTERS + +The real power in writing tests with Test::Base comes from its +filtering capabilities. Test::Base comes with an ever growing set +of useful generic filters than you can sequence and apply to various +test blocks. That means you can specify the block serialization in +the most readable format you can find, and let the filters translate +it into what you really need for a test. It is easy to write your own +filters as well. + +Test::Baseã§ãã¹ããæ¸ãã¨ãã«ãæ¬å½ã«åã«ãªãã®ã¯ããã®ãã£ã«ã¿ãªã³ã° +è½åã§ããTest::Baseã«ã¯ãã¾ãã¾ãªãã¹ããããã¯ã«é åºä»ãã¦é©ç¨ã§ãã +(訳註: thanã¨ãããthatãããªãããª?)ãããã¾ã§ã«å¢ãç¶ãã¦ãã便å©ãª +ä¸è¬çãªãã£ã«ã¿ã®ã»ãããä»å±ãã¾ãããã®ãã¨ã¯ãããªããè¦ã¤ããããã +ãã£ã¨ãå¯èªæ§ã®é«ããã©ã¼ãããã§ãããã¯ã·ãªã¢ãªã¼ã£ã·ã§ã³ãæå®ã§ãã +ãã£ã«ã¿ã§ãããæ¬å½ã«ãã¹ãã«å¿ è¦ãªãã®ã«å¤æããããã¨ãã§ããã¨ãããã¨ã§ãã +ãã¾ãã«ãèªåèªèº«ã®ãã£ã«ã¿ãæ¸ãã®ãç°¡åã§ãã + +Test::Base allows you to specify a list of filters to each data +section of each block. The default filters are C<norm> and C<trim>. +These filters will be applied (in order) to the data after it has been +parsed from the specification and before it is set into its +Test::Base::Block object. + +Test::Baseã§ã¯ãããããã®ãããã¯ã®ããããã®ãã¼ã¿ã»ã¯ã·ã§ã³ã¸ã® +ãã£ã«ã¿ã®ãªã¹ããç¹å®ã§ãã¾ããããã©ã«ãã®ãã£ã«ã¿ã¯ãC<norm>ã¨C<trim>ã§ãã +Test::Base::Blockãªãã¸ã§ã¯ãã«ã»ãããããåã«ãä»æ§ãããã¼ã¹ãããå¾ã +ãããã®ãã£ã«ã¿ã¯(é çªã«)ãã¼ã¿ã«é©ç¨ããã¾ãã + +You can add to the default filter list with the C<filters> function. You +can specify additional filters to a specific block by listing them after +the section name on a data section delimiter line. + +C<filters>é¢æ°ã§ããã©ã«ãã®ãã£ã«ã¿ã¼ã®ãªã¹ãã«å ãããã¨ãåºæ¥ã¾ãã +ãã¼ã¿ã»ã¯ã·ã§ã³ã®ããªãã¿è¡ã«ããã®ã»ã¯ã·ã§ã³åã®å¾ã«ããã£ã«ã¿ã +ãªã¹ããããã¨ã§ãç¹å®ã®ãããã¯ã«ç¹å®ã®è¿½å çãªãã£ã«ã¿ãé©ç¨ã§ãã¾ãã + +Example: + +ä¾: + + use Test::Base; + + filters qw(foo bar); + filters { perl => 'strict' }; + + sub upper { uc(shift) } + + __END__ + + === Test one + --- foo trim chomp upper + ... + + --- bar -norm + ... + + --- perl eval dumper + my @foo = map { + - $_; + } 1..10; + \ @foo; + +Putting a C<-> before a filter on a delimiter line, disables that +filter. + +ããªãã¿è¡ã«ããããã£ã«ã¿ã®åã«C<->ãç½®ãã¨ããã£ã«ã¿ãç¡å¹ã«åºæ¥ã¾ãã + +=head2 ã¹ã«ã© vs ãªã¹ã + +Each filter can take either a scalar or a list as input, and will return +either a scalar or a list. Since filters are chained together, it is +important to learn which filters expect which kind of input and return +which kind of output. + +ããããã®ãã£ã«ã¿ã¯ãå ¥åã¨ãã¦ãã¹ã«ã©ããªã¹ããåããã¹ã«ã©ããªã¹ã +ãè¿ãã¾ãããã£ã«ã¿ã¯ä¸ç·ã«ã¤ãªããããããã©ã®ãã£ã«ã¿ãã©ã®ç¨®é¡ã® +ã¤ã³ããããæå¾ ããã©ã®ç¨®é¡ã®åºåãè¿ãã®ããç¥ã£ã¦ãããã¨ãéè¦ã§ãã + +For example, consider the following filter list: + +ä¾ãã°ãä¸è¨ã®ãã£ã«ã¿ãªã¹ããèãã¦ã¿ã¦ä¸ãã: + + norm trim lines chomp array dumper eval + +The data always starts out as a single scalar string. C<norm> takes a +scalar and returns a scalar. C<trim> takes a list and returns a list, +but a scalar is a valid list. C<lines> takes a scalar and returns a +list. C<chomp> takes a list and returns a list. C<array> takes a list +and returns a scalar (an anonymous array reference containing the list +elements). C<dumper> takes a list and returns a scalar. C<eval> takes a +scalar and creates a list. + +ãã¼ã¿ã¯å¸¸ã«ãåä¸ã®ã¹ã«ã©æååã¨ãã¦å§ã¾ãã¾ããC<norm>㯠+ã¹ã«ã©ãåããã¹ã«ã©ãè¿ãã¾ããC<trim>ã¯ãªã¹ããåãããªã¹ããè¿ãã¾ããã +ã¹ã«ã©ã¯æ£ãããªã¹ãã§ããC<lines>ã¯ã¹ã«ã©ãåãããªã¹ããè¿ãã¾ãã +C<chomp>ã¯ãªã¹ããåãããªã¹ããè¿ãã¾ããC<array>ã¯ãªã¹ããåãã +ã¹ã«ã©(ãªã¹ãè¦ç´ ãå«ãã ç¡åé åãªãã¡ã¬ã³ã¹)ãè¿ãã¾ããC<dumpr>ã¯ãªã¹ãã +åããã¹ã«ã©ãè¿ãã¾ããC<eval>ã¯ã¹ã«ã©ãåããªã¹ããä½ãã¾ãã + +A list of exactly one element works fine as input to a filter requiring +a scalar, but any other list will cause an exception. A scalar in list +context is considered a list of one element. + +æ£ç¢ºã«ä¸ã¤ã®è¦ç´ ã®ãªã¹ãã¯ãã¹ã«ã©ãå¿ è¦ã¨ãããã£ã«ã¿ã¸ã®å ¥åã¨ã㦠+ãã¾ãåãã¾ããã§ãããä»ã®ã©ããªãªã¹ã(訳註:ä¸ã¤ä»¥ä¸ã®è¦ç´ ãæã¤)ãã +ä¾å¤ãèµ·ããã¾ãããªã¹ãã³ã³ããã¹ãã§ä¸ã¤ã®ã¹ã«ã©ã¯ä¸ã¤ã®è¦ç´ ã®ãªã¹ã +ã¨ãã¦èãããã¾ãã + +Data accessor methods for blocks will return a list of values when used +in list context, and the first element of the list in scalar context. +This is usually "the right thing", but be aware. + +ãããã¯ã®ãã¼ã¿ã¢ã¯ã»ãµã¡ã½ããã¯ããªã¹ãã³ã³ããã¹ãã§ã¯å¤ã®ãªã¹ããè¿ãã¾ãã +ã¹ã«ã©ã³ã³ããã¹ãã§ã¯ãªã¹ãã®æåã®è¦ç´ ãè¿ãã¾ãã +ããã¯ãæ®é"æ£ãããã¨"ã§ãããæ°ãä»ãã¦ãã ããã + +=head2 The Stock Filters + +Test::Base comes with large set of stock filters. They are in the +C<Test::Base::Filter> module. See L<Test::Base::Filter> for a listing and +description of these filters. + +Test::Base ã«ã¯ãã¹ããã¯ãã£ã«ã¿å¤æ°ã®ãã£ã«ã¿ã»ãããããã¾ãã +C<Test::Base::Filter>ã¢ã¸ã¥ã¼ã«ã«ããã¾ãããã£ã«ã¿ã®ãªã¹ãã¨èª¬æ㯠+L<Test::Base::Filter>ãè¦ã¦ä¸ããã + +=head2 Rolling Your Own Filters + +Creating filter extensions is very simple. You can either write a +I<function> in the C<main> namespace, or a I<method> in the +C<Test::Base::Filter> namespace or a subclass of it. In either case the +text and any extra arguments are passed in and you return whatever you +want the new value to be. + +ãã£ã«ã¿ã®æ¡å¼µã¯ã¨ã¦ãç°¡åã§ããC<main>åå空éã«I<function>ãæ¸ããã +C<Test::Base::Filter>åå空éãããã®ãµãã¯ã©ã¹ã«I<method>ãæ¸ããã¨ã +ã§ãã¾ããããããã®ã±ã¼ã¹ã§ãããã¹ãã¨ä»å çãªå¼æ°ã渡ããã +æ°ããå¤ã¨ãã¦æ¬²ãããã®ãä½ã§ãè¿ãã¾ãã + +Here is a self explanatory example: + +説æçãªä¾: + + use Test::Base; + + filters 'foo', 'bar=xyz'; + + sub foo { + transform(shift); + } + + sub Test::Base::Filter::bar { + my $self = shift; # The Test::Base::Filter object + my $data = shift; + my $args = $self->arguments; + my $current_block_object = $self->block; + # transform $data in a barish manner + return $data; + } + +If you use the method interface for a filter, you can access the block +internals by calling the C<block> method on the filter object. +Normally you'll probably just use the functional interface, although all +the builtin filters are methods. + +ãã£ã«ã¿ã«ã¡ã½ããã¤ã³ã¿ã¼ãã§ã¼ã¹ã使ãã°ããã£ã«ã¿ãªãã¸ã§ã¯ãã§ã +C<block>ã¡ã½ããã§ãå¼ã¶ãã¨ã§ããããã¯ã®å é¨ã«ã¢ã¯ã»ã¹ã§ãã¾ãã +é常ãããããé¢æ°ã¤ã³ã¿ã¼ãã§ã¼ã¹ã使ãã§ããããã§ãããå ¨ã¦ã® +çµã¿è¾¼ã¿ã®ãã£ã«ã¿ã¯ã¡ã½ããã§ãã + +=head1 OO + +Test::Base has a nice functional interface for simple usage. Under the +hood everything is object oriented. A default Test::Base object is +created and all the functions are really just method calls on it. + +Test::Baseã¯ç°¡åã«ä½¿ããè¯ãé¢æ°ã¤ã³ã¿ã¼ãã§ã¼ã¹ãããã¾ãã +ãã¼ãã®ä¸ã§ãå ¨ã¦ã®ãã®ã¯ãªãã¸ã§ã¯ãæåã§ããããã©ã«ã㧠+Test::Baseãªãã¸ã§ã¯ãã¯ä½ãããå®éã«å ¨ã¦ã®é¢æ°ã¯ã¡ã½ããã§å¼ã³åºãã¾ãã + +This means if you need to get fancy, you can use all the object +oriented stuff too. Just create new Test::Base objects and use the +functions as methods. + +ããã¯ãfancyã«ãªããªããã°ãªããªããªããå ¨ã¦ã®ãªãã¸ã§ã¯ãæåã®ãã®ã +使ããã¨ãåºæ¥ãã¨ãããã¨ã§ããTest::Baseãªãã¸ã§ã¯ããæ°ããä½ã£ã¦ã +ã¡ã½ããã¨ãã¦é¢æ°ã使ãã ãã§ãã + + use Test::Base; + my $blocks1 = Test::Base->new; + my $blocks2 = Test::Base->new; + + $blocks1->delimiters(qw(!!! @@@))->spec_file('test1.txt'); + $blocks2->delimiters(qw(### $$$))->spec_string($test_data); + + plan tests => $blocks1->blocks + $blocks2->blocks; + + # ... etc + +=head1 C<Test::Base::Block>ã¯ã©ã¹ + +In Test::Base, blocks are exposed as Test::Base::Block objects. This +section lists the methods that can be called on a Test::Base::Block +object. Of course, each data section name is also available as a method. + +Test::Baseã«ã¯ãTest::Base::Blockãªãã¸ã§ã¯ãã¨ãã¦ãblocksãexposeããã¦ãã¾ãã +ãã®ã»ã¯ã·ã§ã³ã§ã¯ãTest::Base::Blockãªãã¸ã§ã¯ãã§å¼ã¹ãã¡ã½ãããä¸è¦§ãã¾ãã +ãã¡ãããããããã®ãã¼ã¿ã»ã¯ã·ã§ã³åãã¾ããã¡ã½ããã¨ãã¦ä½¿ãã¾ãã + +=head2 name() + +This is the optional short description of a block, that is specified on the +block separator line. + +blockã®ãªãã·ã§ãã«ãªçã説æã§ãããããã¯ã®ã»ãã¬ã¼ã¿ã®è¡ã«è¨å ¥ããã¾ãã + +=head2 description() + +This is an optional long description of the block. It is the text taken from +between the block separator and the first data section. + +blockã®ãªãã·ã§ãã«ãªé·ã説æã§ãããããã¯ã»ãã¬ã¼ã¿ã¨æåã®ãã¼ã¿ã»ãã¬ã¼ã¿ã® +éã«æ¸ããã¦ããããã¹ãã§ãã + +=head2 seq_num() + +Returns a sequence number for this block. Sequence numbers begin with 1. + +ãããã¯ã®ã·ã¼ã±ã³ã¹çªå·ãè¿ãã¾ããã·ã¼ã±ã³ã¹çªå·ã¯1ããå§ã¾ãã¾ãã + +=head2 blocks_object() + +Returns the Test::Base object that owns this block. + +ãã®ãããã¯ãæã£ã¦ããTest::Baseãªãã¸ã§ã¯ããè¿ãã¾ãã + +=head2 run_filters() + +Run the filters on the data sections of the blocks. You don't need to +use this method unless you also used the C<filters_delay> function. + +ãããã¯ã®ãã¼ã¿ã»ã¯ã·ã§ã³ã®ãã£ã«ã¿ã¼ãå®è¡ãã¾ãã +C<filter_delay>é¢æ°ã使ããªããã°ããã®ã¡ã½ããã使ãå¿ è¦ã¯ããã¾ããã + +=head2 is_filtered() + +Returns true if filters have already been run for this block. + +ãã®ãããã¯ã§æ¢ã«ãã£ã«ã¿ã¼ãå®è¡ããã¦ããã°ãçãè¿ãã¾ãã + +=head2 original_values() + +Returns a hash of the original, unfiltered values of each data section. + +ããããã®ãã¼ã¿ã»ã¯ã·ã§ã³ã®ãã£ã«ã¿ã¼ããã¦ããªãã +ãªãªã¸ãã«ã®ããã·ã¥ãè¿ãã¾ãã + +=head1 ãµãã¯ã©ã¹å + +One of the nicest things about Test::Base is that it is easy to +subclass. This is very important, because in your personal project, you +will likely want to extend Test::Base with your own filters and other +reusable pieces of your test framework. + +Test::Baseã®ä¸çªè¯ãæ©è½ã®ä¸ã¤ã¯ããµãã¯ã©ã¹ãä½ãã®ãç°¡åãªãã¨ã§ãã +ãã®ãã¨ã¯ã¨ã¦ãéè¦ã§ããèªåã®å人çãªããã¸ã§ã¯ãã§ãèªåã®ãã¹ã +ãã¬ã¼ã ã¯ã¼ã¯ã®ãèªåèªèº«ã®ãã£ã«ã¿ã¼ãä»ã®åå©ç¨å¯è½ãªãã®ã§ã +ããããTest::Baseãæ¡å¼µãããã§ãããããã + +Here is an example of a subclass: + +ãµãã¯ã©ã¹ã®ä¾ã§ã: + + package MyTestStuff; + use Test::Base -Base; + + our @EXPORT = qw(some_func); + + sub some_func { + (my ($self), @_) = find_my_self(@_); + ... + } + + package MyTestStuff::Block; + use base 'Test::Base::Block'; + + sub desc { + $self->description(@_); + } + + package MyTestStuff::Filter; + use base 'Test::Base::Filter'; + + sub upper { + $self->assert_scalar(@_); + uc(shift); + } + +Note that you don't have to re-Export all the functions from +Test::Base. That happens automatically, due to the powers of Spiffy. + +Test::Baseããå ¨ã¦ã®é¢æ°ãå度ã¨ã¯ã¹ãã¼ãããå¿ è¦ã¯ããã¾ããã +Spiffyã®åã§ãèªåçã«è¡ããã¾ãã + +The first line in C<some_func> allows it to be called as either a +function or a method in the test code. + +C<some_func>ã®æåã®è¡ã§ããã¹ãã³ã¼ãã§ãé¢æ°ãã¡ã½ããã®ã©ã¡ãã§ã +å¼ã¹ãããã«ãã¦ãã¾ãã + +=head1 é å¸ãµãã¼ã + +You might be thinking that you do not want to use Test::Base in you +modules, because it adds an installation dependency. Fear not. +Module::Build takes care of that. + +ã¤ã³ã¹ãã¼ã«ã«ä¾åæ§ãå ããããªãã®ã§ãèªåã®ã¢ã¸ã¥ã¼ã«ã§ +Test::Baseã使ããããªãã¨æãããããã¾ããã +æããªãã§ãã ãããModule::Buildãé¢åãã¿ã¦ããã¾ãã + +Just write a Makefile.PL that looks something like this: + +Makefile.PLã«ã次ã®ããã«æ¸ãã¦ãã ãã: + + use inc::Module::Install; + + name 'Foo'; + all_from 'lib/Foo.pm'; + + use_test_base; + + WriteAll; + +The line with C<use_test_base> will automatically bundle all the code +the user needs to run Test::Base based tests. + +C<use_test_base>ã®è¡ãèªåçã«ãTest::Baseã«åºã¥ãã¦ãããã¹ããå®è¡ããã®ã« +ã¦ã¼ã¶ã¼ãå¿ è¦ãªå ¨ã¦ã®ã³ã¼ãããã³ãã«ãã¾ãã + +=head1 ä»ã®ã¯ã¼ã«ãªæ©è½ + +Test::Base automatically adds: + +Test::Baseã¯èªåçã«è¿½å ãã¾ã: + + use strict; + use warnings; + +to all of your test scripts and Test::Base subclasses. A Spiffy +feature indeed. + +å ¨ã¦ã®ãã¹ãã¹ã¯ãªããã¨Test::Baseãµãã¯ã©ã¹ã«ãå®éã«ã¯ãSpiffy +ã®æ©è½ã§ãã + +=head1 HISTORY + +This module started its life with the horrible and ridicule inducing +name C<Test::Chunks>. It was renamed to C<Test::Base> with the hope +that it would be seen for the very useful module that it has become. If +you are switching from C<Test::Chunks> to C<Test::Base>, simply +substitute the concept and usage of C<chunks> to C<blocks>. + + +C<Test::Chunks>ã¨ããååã«å«ã¾ãããã²ã©ããã®ã¨æå¼ã¨ã§ãã®å½ +ãå§ãã¾ãããã¨ã¦ã便å©ãªã¢ã¸ã¥ã¼ã«ã«ãªãã¨åãããã¨ãæãã§ã +C<Test::Base>ã¨ããååã«å¤æ´ããã¾ããã +C<Test::Chunks>ããC<Test::Base>ã«å¤æ´ãããªããåç´ã«ã +C<chunks>ã®ã³ã³ã»ããã¨ä½¿ãæ¹ã®ä»£ããã«ãC<blocks>ã«ãã¦ãã ããã + +=head1 AUTHOR + +Ingy d旦t Net <ingy****@cpan*****> + +=head1 COPYRIGHT + +Copyright (c) 2006. Ingy d旦t Net. All rights reserved. +Copyright (c) 2005. Brian Ingerson. All rights reserved. + +This program is free software; you can redistribute it and/or modify it +under the same terms as Perl itself. + +See http://www.perl.com/perl/misc/Artistic.html + +=cut