Add built local::lib
[catagits/Gitalist.git] / local-lib5 / man / man3 / Test::Tutorial.3pm
diff --git a/local-lib5/man/man3/Test::Tutorial.3pm b/local-lib5/man/man3/Test::Tutorial.3pm
new file mode 100644 (file)
index 0000000..38f0cae
--- /dev/null
@@ -0,0 +1,841 @@
+.\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.3
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sh \" Subsection heading
+.br
+.if t .Sp
+.ne 5
+.PP
+\fB\\$1\fR
+.PP
+..
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings.  \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote.  | will give a
+.\" real vertical bar.  \*(C+ will give a nicer C++.  Capital omega is used to
+.\" do unbreakable dashes and therefore won't be available.  \*(C` and \*(C'
+.\" expand to `' in nroff, nothing in troff, for use with C<>.
+.tr \(*W-|\(bv\*(Tr
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+.    ds -- \(*W-
+.    ds PI pi
+.    if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+.    if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\"  diablo 12 pitch
+.    ds L" ""
+.    ds R" ""
+.    ds C` ""
+.    ds C' ""
+'br\}
+.el\{\
+.    ds -- \|\(em\|
+.    ds PI \(*p
+.    ds L" ``
+.    ds R" ''
+'br\}
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index
+.\" entries marked with X<> in POD.  Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.if \nF \{\
+.    de IX
+.    tm Index:\\$1\t\\n%\t"\\$2"
+..
+.    nr % 0
+.    rr F
+.\}
+.\"
+.\" For nroff, turn off justification.  Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.hy 0
+.if n .na
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear.  Run.  Save yourself.  No user-serviceable parts.
+.    \" fudge factors for nroff and troff
+.if n \{\
+.    ds #H 0
+.    ds #V .8m
+.    ds #F .3m
+.    ds #[ \f1
+.    ds #] \fP
+.\}
+.if t \{\
+.    ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+.    ds #V .6m
+.    ds #F 0
+.    ds #[ \&
+.    ds #] \&
+.\}
+.    \" simple accents for nroff and troff
+.if n \{\
+.    ds ' \&
+.    ds ` \&
+.    ds ^ \&
+.    ds , \&
+.    ds ~ ~
+.    ds /
+.\}
+.if t \{\
+.    ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+.    ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+.    ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+.    ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+.    ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+.    ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+.    \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+.    \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+.    \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+.    ds : e
+.    ds 8 ss
+.    ds o a
+.    ds d- d\h'-1'\(ga
+.    ds D- D\h'-1'\(hy
+.    ds th \o'bp'
+.    ds Th \o'LP'
+.    ds ae ae
+.    ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "Test::Tutorial 3"
+.TH Test::Tutorial 3 "2009-09-02" "perl v5.8.7" "User Contributed Perl Documentation"
+.SH "NAME"
+Test::Tutorial \- A tutorial about writing really basic tests
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+\&\fI\s-1AHHHHHHH\s0!!!!  \s-1NOT\s0 \s-1TESTING\s0!  Anything but testing!  
+Beat me, whip me, send me to Detroit, but don't make 
+me write tests!\fR
+.PP
+\&\fI*sob*\fR
+.PP
+\&\fIBesides, I don't know how to write the damned things.\fR
+.PP
+Is this you?  Is writing tests right up there with writing
+documentation and having your fingernails pulled out?  Did you open up
+a test and read 
+.PP
+.Vb 1
+\&    ######## We start with some black magic
+.Ve
+.PP
+and decide that's quite enough for you?
+.PP
+It's ok.  That's all gone now.  We've done all the black magic for
+you.  And here are the tricks...
+.Sh "Nuts and bolts of testing."
+.IX Subsection "Nuts and bolts of testing."
+Here's the most basic test program.
+.PP
+.Vb 1
+\&    #!/usr/bin/perl \-w
+.Ve
+.PP
+.Vb 1
+\&    print "1..1\en";
+.Ve
+.PP
+.Vb 1
+\&    print 1 + 1 == 2 ? "ok 1\en" : "not ok 1\en";
+.Ve
+.PP
+since 1 + 1 is 2, it prints:
+.PP
+.Vb 2
+\&    1..1
+\&    ok 1
+.Ve
+.PP
+What this says is: \f(CW1..1\fR \*(L"I'm going to run one test.\*(R" [1] \f(CW\*(C`ok 1\*(C'\fR
+\&\*(L"The first test passed\*(R".  And that's about all magic there is to
+testing.  Your basic unit of testing is the \fIok\fR.  For each thing you
+test, an \f(CW\*(C`ok\*(C'\fR is printed.  Simple.  \fBTest::Harness\fR interprets your test
+results to determine if you succeeded or failed (more on that later).
+.PP
+Writing all these print statements rapidly gets tedious.  Fortunately,
+there's \fBTest::Simple\fR.  It has one function, \f(CW\*(C`ok()\*(C'\fR.
+.PP
+.Vb 1
+\&    #!/usr/bin/perl \-w
+.Ve
+.PP
+.Vb 1
+\&    use Test::Simple tests => 1;
+.Ve
+.PP
+.Vb 1
+\&    ok( 1 + 1 == 2 );
+.Ve
+.PP
+and that does the same thing as the code above.  \f(CW\*(C`ok()\*(C'\fR is the backbone
+of Perl testing, and we'll be using it instead of roll-your-own from
+here on.  If \f(CW\*(C`ok()\*(C'\fR gets a true value, the test passes.  False, it
+fails.
+.PP
+.Vb 1
+\&    #!/usr/bin/perl \-w
+.Ve
+.PP
+.Vb 3
+\&    use Test::Simple tests => 2;
+\&    ok( 1 + 1 == 2 );
+\&    ok( 2 + 2 == 5 );
+.Ve
+.PP
+from that comes
+.PP
+.Vb 5
+\&    1..2
+\&    ok 1
+\&    not ok 2
+\&    #     Failed test (test.pl at line 5)
+\&    # Looks like you failed 1 tests of 2.
+.Ve
+.PP
+\&\f(CW1..2\fR \*(L"I'm going to run two tests.\*(R"  This number is used to ensure
+your test program ran all the way through and didn't die or skip some
+tests.  \f(CW\*(C`ok 1\*(C'\fR \*(L"The first test passed.\*(R"  \f(CW\*(C`not ok 2\*(C'\fR \*(L"The second test
+failed\*(R".  Test::Simple helpfully prints out some extra commentary about
+your tests.
+.PP
+It's not scary.  Come, hold my hand.  We're going to give an example
+of testing a module.  For our example, we'll be testing a date
+library, \fBDate::ICal\fR.  It's on \s-1CPAN\s0, so download a copy and follow
+along. [2]
+.Sh "Where to start?"
+.IX Subsection "Where to start?"
+This is the hardest part of testing, where do you start?  People often
+get overwhelmed at the apparent enormity of the task of testing a
+whole module.  Best place to start is at the beginning.  Date::ICal is
+an object-oriented module, and that means you start by making an
+object.  So we test \f(CW\*(C`new()\*(C'\fR.
+.PP
+.Vb 1
+\&    #!/usr/bin/perl \-w
+.Ve
+.PP
+.Vb 1
+\&    use Test::Simple tests => 2;
+.Ve
+.PP
+.Vb 1
+\&    use Date::ICal;
+.Ve
+.PP
+.Vb 3
+\&    my $ical = Date::ICal\->new;         # create an object
+\&    ok( defined $ical );                # check that we got something
+\&    ok( $ical\->isa('Date::ICal') );     # and it's the right class
+.Ve
+.PP
+run that and you should get:
+.PP
+.Vb 3
+\&    1..2
+\&    ok 1
+\&    ok 2
+.Ve
+.PP
+congratulations, you've written your first useful test.
+.Sh "Names"
+.IX Subsection "Names"
+That output isn't terribly descriptive, is it?  When you have two
+tests you can figure out which one is #2, but what if you have 102?
+.PP
+Each test can be given a little descriptive name as the second
+argument to \f(CW\*(C`ok()\*(C'\fR.
+.PP
+.Vb 1
+\&    use Test::Simple tests => 2;
+.Ve
+.PP
+.Vb 2
+\&    ok( defined $ical,              'new() returned something' );
+\&    ok( $ical\->isa('Date::ICal'),   "  and it's the right class" );
+.Ve
+.PP
+So now you'd see...
+.PP
+.Vb 3
+\&    1..2
+\&    ok 1 \- new() returned something
+\&    ok 2 \-   and it's the right class
+.Ve
+.Sh "Test the manual"
+.IX Subsection "Test the manual"
+Simplest way to build up a decent testing suite is to just test what
+the manual says it does. [3] Let's pull something out of the 
+\&\*(L"\s-1SYNOPSIS\s0\*(R" in Date::ICal and test that all its bits work.
+.PP
+.Vb 1
+\&    #!/usr/bin/perl \-w
+.Ve
+.PP
+.Vb 1
+\&    use Test::Simple tests => 8;
+.Ve
+.PP
+.Vb 1
+\&    use Date::ICal;
+.Ve
+.PP
+.Vb 3
+\&    $ical = Date::ICal\->new( year => 1964, month => 10, day => 16, 
+\&                             hour => 16, min => 12, sec => 47, 
+\&                             tz => '0530' );
+.Ve
+.PP
+.Vb 8
+\&    ok( defined $ical,            'new() returned something' );
+\&    ok( $ical\->isa('Date::ICal'), "  and it's the right class" );
+\&    ok( $ical\->sec   == 47,       '  sec()'   );
+\&    ok( $ical\->min   == 12,       '  min()'   );    
+\&    ok( $ical\->hour  == 16,       '  hour()'  );
+\&    ok( $ical\->day   == 17,       '  day()'   );
+\&    ok( $ical\->month == 10,       '  month()' );
+\&    ok( $ical\->year  == 1964,     '  year()'  );
+.Ve
+.PP
+run that and you get:
+.PP
+.Vb 11
+\&    1..8
+\&    ok 1 \- new() returned something
+\&    ok 2 \-   and it's the right class
+\&    ok 3 \-   sec()
+\&    ok 4 \-   min()
+\&    ok 5 \-   hour()
+\&    not ok 6 \-   day()
+\&    #     Failed test (\- at line 16)
+\&    ok 7 \-   month()
+\&    ok 8 \-   year()
+\&    # Looks like you failed 1 tests of 8.
+.Ve
+.PP
+Whoops, a failure! [4] Test::Simple helpfully lets us know on what line
+the failure occurred, but not much else.  We were supposed to get 17,
+but we didn't.  What did we get??  Dunno.  We'll have to re-run the
+test in the debugger or throw in some print statements to find out.
+.PP
+Instead, we'll switch from \fBTest::Simple\fR to \fBTest::More\fR.  \fBTest::More\fR
+does everything \fBTest::Simple\fR does, and more!  In fact, Test::More does
+things \fIexactly\fR the way Test::Simple does.  You can literally swap
+Test::Simple out and put Test::More in its place.  That's just what
+we're going to do.
+.PP
+Test::More does more than Test::Simple.  The most important difference
+at this point is it provides more informative ways to say \*(L"ok\*(R".
+Although you can write almost any test with a generic \f(CW\*(C`ok()\*(C'\fR, it
+can't tell you what went wrong.  Instead, we'll use the \f(CW\*(C`is()\*(C'\fR
+function, which lets us declare that something is supposed to be the
+same as something else:
+.PP
+.Vb 1
+\&    #!/usr/bin/perl \-w
+.Ve
+.PP
+.Vb 1
+\&    use Test::More tests => 8;
+.Ve
+.PP
+.Vb 1
+\&    use Date::ICal;
+.Ve
+.PP
+.Vb 3
+\&    $ical = Date::ICal\->new( year => 1964, month => 10, day => 16, 
+\&                             hour => 16, min => 12, sec => 47, 
+\&                             tz => '0530' );
+.Ve
+.PP
+.Vb 8
+\&    ok( defined $ical,            'new() returned something' );
+\&    ok( $ical\->isa('Date::ICal'), "  and it's the right class" );
+\&    is( $ical\->sec,     47,       '  sec()'   );
+\&    is( $ical\->min,     12,       '  min()'   );    
+\&    is( $ical\->hour,    16,       '  hour()'  );
+\&    is( $ical\->day,     17,       '  day()'   );
+\&    is( $ical\->month,   10,       '  month()' );
+\&    is( $ical\->year,    1964,     '  year()'  );
+.Ve
+.PP
+"Is \f(CW\*(C`$ical\->sec\*(C'\fR 47?\*(L"  \*(R"Is \f(CW\*(C`$ical\->min\*(C'\fR 12?"  With \f(CW\*(C`is()\*(C'\fR in place,
+you get some more information
+.PP
+.Vb 13
+\&    1..8
+\&    ok 1 \- new() returned something
+\&    ok 2 \-   and it's the right class
+\&    ok 3 \-   sec()
+\&    ok 4 \-   min()
+\&    ok 5 \-   hour()
+\&    not ok 6 \-   day()
+\&    #     Failed test (\- at line 16)
+\&    #          got: '16'
+\&    #     expected: '17'
+\&    ok 7 \-   month()
+\&    ok 8 \-   year()
+\&    # Looks like you failed 1 tests of 8.
+.Ve
+.PP
+letting us know that \f(CW\*(C`$ical\->day\*(C'\fR returned 16, but we expected 17.  A
+quick check shows that the code is working fine, we made a mistake
+when writing up the tests.  Just change it to:
+.PP
+.Vb 1
+\&    is( $ical\->day,     16,       '  day()'   );
+.Ve
+.PP
+and everything works.
+.PP
+So any time you're doing a \*(L"this equals that\*(R" sort of test, use \f(CW\*(C`is()\*(C'\fR.
+It even works on arrays.  The test is always in scalar context, so you
+can test how many elements are in a list this way. [5]
+.PP
+.Vb 1
+\&    is( @foo, 5, 'foo has 5 elements' );
+.Ve
+.Sh "Sometimes the tests are wrong"
+.IX Subsection "Sometimes the tests are wrong"
+Which brings us to a very important lesson.  Code has bugs.  Tests are
+code.  Ergo, tests have bugs.  A failing test could mean a bug in the
+code, but don't discount the possibility that the test is wrong.
+.PP
+On the flip side, don't be tempted to prematurely declare a test
+incorrect just because you're having trouble finding the bug.
+Invalidating a test isn't something to be taken lightly, and don't use
+it as a cop out to avoid work.
+.Sh "Testing lots of values"
+.IX Subsection "Testing lots of values"
+We're going to be wanting to test a lot of dates here, trying to trick
+the code with lots of different edge cases.  Does it work before 1970?
+After 2038?  Before 1904?  Do years after 10,000 give it trouble?
+Does it get leap years right?  We could keep repeating the code above,
+or we could set up a little try/expect loop.
+.PP
+.Vb 2
+\&    use Test::More tests => 32;
+\&    use Date::ICal;
+.Ve
+.PP
+.Vb 12
+\&    my %ICal_Dates = (
+\&            # An ICal string     And the year, month, day
+\&            #                    hour, minute and second we expect.
+\&            '19971024T120000' =>    # from the docs.
+\&                                [ 1997, 10, 24, 12,  0,  0 ],
+\&            '20390123T232832' =>    # after the Unix epoch
+\&                                [ 2039,  1, 23, 23, 28, 32 ],
+\&            '19671225T000000' =>    # before the Unix epoch
+\&                                [ 1967, 12, 25,  0,  0,  0 ],
+\&            '18990505T232323' =>    # before the MacOS epoch
+\&                                [ 1899,  5,  5, 23, 23, 23 ],
+\&    );
+.Ve
+.PP
+.Vb 2
+\&    while( my($ical_str, $expect) = each %ICal_Dates ) {
+\&        my $ical = Date::ICal\->new( ical => $ical_str );
+.Ve
+.PP
+.Vb 2
+\&        ok( defined $ical,            "new(ical => '$ical_str')" );
+\&        ok( $ical\->isa('Date::ICal'), "  and it's the right class" );
+.Ve
+.PP
+.Vb 7
+\&        is( $ical\->year,    $expect\->[0],     '  year()'  );
+\&        is( $ical\->month,   $expect\->[1],     '  month()' );
+\&        is( $ical\->day,     $expect\->[2],     '  day()'   );
+\&        is( $ical\->hour,    $expect\->[3],     '  hour()'  );
+\&        is( $ical\->min,     $expect\->[4],     '  min()'   );    
+\&        is( $ical\->sec,     $expect\->[5],     '  sec()'   );
+\&    }
+.Ve
+.PP
+So now we can test bunches of dates by just adding them to
+\&\f(CW%ICal_Dates\fR.  Now that it's less work to test with more dates, you'll
+be inclined to just throw more in as you think of them.
+Only problem is, every time we add to that we have to keep adjusting
+the \f(CW\*(C`use Test::More tests => ##\*(C'\fR line.  That can rapidly get
+annoying.  There's two ways to make this work better.
+.PP
+First, we can calculate the plan dynamically using the \f(CW\*(C`plan()\*(C'\fR
+function.
+.PP
+.Vb 2
+\&    use Test::More;
+\&    use Date::ICal;
+.Ve
+.PP
+.Vb 3
+\&    my %ICal_Dates = (
+\&        ...same as before...
+\&    );
+.Ve
+.PP
+.Vb 2
+\&    # For each key in the hash we're running 8 tests.
+\&    plan tests => keys(%ICal_Dates) * 8;
+.Ve
+.PP
+.Vb 1
+\&    ...and then your tests...
+.Ve
+.PP
+Or to be even more flexible, we use \f(CW\*(C`no_plan\*(C'\fR.  This means we're just
+running some tests, don't know how many. [6]
+.PP
+.Vb 1
+\&    use Test::More 'no_plan';   # instead of tests => 32
+.Ve
+.PP
+now we can just add tests and not have to do all sorts of math to
+figure out how many we're running.
+.Sh "Informative names"
+.IX Subsection "Informative names"
+Take a look at this line here
+.PP
+.Vb 1
+\&    ok( defined $ical,            "new(ical => '$ical_str')" );
+.Ve
+.PP
+we've added more detail about what we're testing and the ICal string
+itself we're trying out to the name.  So you get results like:
+.PP
+.Vb 8
+\&    ok 25 \- new(ical => '19971024T120000')
+\&    ok 26 \-   and it's the right class
+\&    ok 27 \-   year()
+\&    ok 28 \-   month()
+\&    ok 29 \-   day()
+\&    ok 30 \-   hour()
+\&    ok 31 \-   min()
+\&    ok 32 \-   sec()
+.Ve
+.PP
+if something in there fails, you'll know which one it was and that
+will make tracking down the problem easier.  So try to put a bit of
+debugging information into the test names.
+.PP
+Describe what the tests test, to make debugging a failed test easier
+for you or for the next person who runs your test.
+.Sh "Skipping tests"
+.IX Subsection "Skipping tests"
+Poking around in the existing Date::ICal tests, I found this in
+\&\fIt/01sanity.t\fR [7]
+.PP
+.Vb 1
+\&    #!/usr/bin/perl \-w
+.Ve
+.PP
+.Vb 2
+\&    use Test::More tests => 7;
+\&    use Date::ICal;
+.Ve
+.PP
+.Vb 3
+\&    # Make sure epoch time is being handled sanely.
+\&    my $t1 = Date::ICal\->new( epoch => 0 );
+\&    is( $t1\->epoch, 0,          "Epoch time of 0" );
+.Ve
+.PP
+.Vb 2
+\&    # XXX This will only work on unix systems.
+\&    is( $t1\->ical, '19700101Z', "  epoch to ical" );
+.Ve
+.PP
+.Vb 3
+\&    is( $t1\->year,  1970,       "  year()"  );
+\&    is( $t1\->month, 1,          "  month()" );
+\&    is( $t1\->day,   1,          "  day()"   );
+.Ve
+.PP
+.Vb 3
+\&    # like the tests above, but starting with ical instead of epoch
+\&    my $t2 = Date::ICal\->new( ical => '19700101Z' );
+\&    is( $t2\->ical, '19700101Z', "Start of epoch in ICal notation" );
+.Ve
+.PP
+.Vb 1
+\&    is( $t2\->epoch, 0,          "  and back to ICal" );
+.Ve
+.PP
+The beginning of the epoch is different on most non-Unix operating
+systems [8].  Even though Perl smooths out the differences for the
+most part, certain ports do it differently.  MacPerl is one off the
+top of my head. [9]  So rather than just putting a comment in the test,
+we can explicitly say it's never going to work and skip the test.
+.PP
+.Vb 2
+\&    use Test::More tests => 7;
+\&    use Date::ICal;
+.Ve
+.PP
+.Vb 3
+\&    # Make sure epoch time is being handled sanely.
+\&    my $t1 = Date::ICal\->new( epoch => 0 );
+\&    is( $t1\->epoch, 0,          "Epoch time of 0" );
+.Ve
+.PP
+.Vb 3
+\&    SKIP: {
+\&        skip('epoch to ICal not working on MacOS', 6) 
+\&            if $^O eq 'MacOS';
+.Ve
+.PP
+.Vb 1
+\&        is( $t1\->ical, '19700101Z', "  epoch to ical" );
+.Ve
+.PP
+.Vb 3
+\&        is( $t1\->year,  1970,       "  year()"  );
+\&        is( $t1\->month, 1,          "  month()" );
+\&        is( $t1\->day,   1,          "  day()"   );
+.Ve
+.PP
+.Vb 3
+\&        # like the tests above, but starting with ical instead of epoch
+\&        my $t2 = Date::ICal\->new( ical => '19700101Z' );
+\&        is( $t2\->ical, '19700101Z', "Start of epoch in ICal notation" );
+.Ve
+.PP
+.Vb 2
+\&        is( $t2\->epoch, 0,          "  and back to ICal" );
+\&    }
+.Ve
+.PP
+A little bit of magic happens here.  When running on anything but
+MacOS, all the tests run normally.  But when on MacOS, \f(CW\*(C`skip()\*(C'\fR causes
+the entire contents of the \s-1SKIP\s0 block to be jumped over.  It's never
+run.  Instead, it prints special output that tells Test::Harness that
+the tests have been skipped.
+.PP
+.Vb 8
+\&    1..7
+\&    ok 1 \- Epoch time of 0
+\&    ok 2 # skip epoch to ICal not working on MacOS
+\&    ok 3 # skip epoch to ICal not working on MacOS
+\&    ok 4 # skip epoch to ICal not working on MacOS
+\&    ok 5 # skip epoch to ICal not working on MacOS
+\&    ok 6 # skip epoch to ICal not working on MacOS
+\&    ok 7 # skip epoch to ICal not working on MacOS
+.Ve
+.PP
+This means your tests won't fail on MacOS.  This means less emails
+from MacPerl users telling you about failing tests that you know will
+never work.  You've got to be careful with skip tests.  These are for
+tests which don't work and \fInever will\fR.  It is not for skipping
+genuine bugs (we'll get to that in a moment).
+.PP
+The tests are wholly and completely skipped. [10]  This will work.
+.PP
+.Vb 2
+\&    SKIP: {
+\&        skip("I don't wanna die!");
+.Ve
+.PP
+.Vb 2
+\&        die, die, die, die, die;
+\&    }
+.Ve
+.Sh "Todo tests"
+.IX Subsection "Todo tests"
+Thumbing through the Date::ICal man page, I came across this:
+.PP
+.Vb 1
+\&   ical
+.Ve
+.PP
+.Vb 1
+\&       $ical_string = $ical\->ical;
+.Ve
+.PP
+.Vb 2
+\&   Retrieves, or sets, the date on the object, using any
+\&   valid ICal date/time string.
+.Ve
+.PP
+\&\*(L"Retrieves or sets\*(R".  Hmmm, didn't see a test for using \f(CW\*(C`ical()\*(C'\fR to set
+the date in the Date::ICal test suite.  So I'll write one.
+.PP
+.Vb 2
+\&    use Test::More tests => 1;
+\&    use Date::ICal;
+.Ve
+.PP
+.Vb 3
+\&    my $ical = Date::ICal\->new;
+\&    $ical\->ical('20201231Z');
+\&    is( $ical\->ical, '20201231Z',   'Setting via ical()' );
+.Ve
+.PP
+run that and I get
+.PP
+.Vb 6
+\&    1..1
+\&    not ok 1 \- Setting via ical()
+\&    #     Failed test (\- at line 6)
+\&    #          got: '20010814T233649Z'
+\&    #     expected: '20201231Z'
+\&    # Looks like you failed 1 tests of 1.
+.Ve
+.PP
+Whoops!  Looks like it's unimplemented.  Let's assume we don't have
+the time to fix this. [11] Normally, you'd just comment out the test
+and put a note in a todo list somewhere.  Instead, we're going to
+explicitly state \*(L"this test will fail\*(R" by wrapping it in a \f(CW\*(C`TODO\*(C'\fR block.
+.PP
+.Vb 1
+\&    use Test::More tests => 1;
+.Ve
+.PP
+.Vb 2
+\&    TODO: {
+\&        local $TODO = 'ical($ical) not yet implemented';
+.Ve
+.PP
+.Vb 2
+\&        my $ical = Date::ICal\->new;
+\&        $ical\->ical('20201231Z');
+.Ve
+.PP
+.Vb 2
+\&        is( $ical\->ical, '20201231Z',   'Setting via ical()' );
+\&    }
+.Ve
+.PP
+Now when you run, it's a little different:
+.PP
+.Vb 4
+\&    1..1
+\&    not ok 1 \- Setting via ical() # TODO ical($ical) not yet implemented
+\&    #          got: '20010822T201551Z'
+\&    #     expected: '20201231Z'
+.Ve
+.PP
+Test::More doesn't say \*(L"Looks like you failed 1 tests of 1\*(R".  That '#
+\&\s-1TODO\s0' tells Test::Harness \*(L"this is supposed to fail\*(R" and it treats a
+failure as a successful test.  So you can write tests even before
+you've fixed the underlying code.
+.PP
+If a \s-1TODO\s0 test passes, Test::Harness will report it \*(L"\s-1UNEXPECTEDLY\s0
+\&\s-1SUCCEEDED\s0\*(R".  When that happens, you simply remove the \s-1TODO\s0 block with
+\&\f(CW\*(C`local $TODO\*(C'\fR and turn it into a real test.
+.Sh "Testing with taint mode."
+.IX Subsection "Testing with taint mode."
+Taint mode is a funny thing.  It's the globalest of all global
+features.  Once you turn it on, it affects \fIall\fR code in your program
+and \fIall\fR modules used (and all the modules they use).  If a single
+piece of code isn't taint clean, the whole thing explodes.  With that
+in mind, it's very important to ensure your module works under taint
+mode.
+.PP
+It's very simple to have your tests run under taint mode.  Just throw
+a \f(CW\*(C`\-T\*(C'\fR into the \f(CW\*(C`#!\*(C'\fR line.  Test::Harness will read the switches
+in \f(CW\*(C`#!\*(C'\fR and use them to run your tests.
+.PP
+.Vb 1
+\&    #!/usr/bin/perl \-Tw
+.Ve
+.PP
+.Vb 1
+\&    ...test normally here...
+.Ve
+.PP
+So when you say \f(CW\*(C`make test\*(C'\fR it will be run with taint mode and
+warnings on.
+.SH "FOOTNOTES"
+.IX Header "FOOTNOTES"
+.IP "1" 4
+.IX Item "1"
+The first number doesn't really mean anything, but it has to be 1.
+It's the second number that's important.
+.IP "2" 4
+.IX Item "2"
+For those following along at home, I'm using version 1.31.  It has
+some bugs, which is good \*(-- we'll uncover them with our tests.
+.IP "3" 4
+.IX Item "3"
+You can actually take this one step further and test the manual
+itself.  Have a look at \fBTest::Inline\fR (formerly \fBPod::Tests\fR).
+.IP "4" 4
+.IX Item "4"
+Yes, there's a mistake in the test suite.  What!  Me, contrived?
+.IP "5" 4
+.IX Item "5"
+We'll get to testing the contents of lists later.
+.IP "6" 4
+.IX Item "6"
+But what happens if your test program dies halfway through?!  Since we
+didn't say how many tests we're going to run, how can we know it
+failed?  No problem, Test::More employs some magic to catch that death
+and turn the test into a failure, even if every test passed up to that
+point.
+.IP "7" 4
+.IX Item "7"
+I cleaned it up a little.
+.IP "8" 4
+.IX Item "8"
+Most Operating Systems record time as the number of seconds since a
+certain date.  This date is the beginning of the epoch.  Unix's starts
+at midnight January 1st, 1970 \s-1GMT\s0.
+.IP "9" 4
+.IX Item "9"
+MacOS's epoch is midnight January 1st, 1904.  \s-1VMS\s0's is midnight,
+November 17th, 1858, but vmsperl emulates the Unix epoch so it's not a
+problem.
+.IP "10" 4
+.IX Item "10"
+As long as the code inside the \s-1SKIP\s0 block at least compiles.  Please
+don't ask how.  No, it's not a filter.
+.IP "11" 4
+.IX Item "11"
+Do \s-1NOT\s0 be tempted to use \s-1TODO\s0 tests as a way to avoid fixing simple
+bugs!
+.SH "AUTHORS"
+.IX Header "AUTHORS"
+Michael G Schwern <schwern@pobox.com> and the perl-qa dancers!
+.SH "COPYRIGHT"
+.IX Header "COPYRIGHT"
+Copyright 2001 by Michael G Schwern <schwern@pobox.com>.
+.PP
+This documentation is free; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+.PP
+Irrespective of its distribution, all code examples in these files
+are hereby placed into the public domain.  You are permitted and
+encouraged to use this code in your own programs for fun
+or for profit as you see fit.  A simple comment in the code giving
+credit would be courteous but is not required.