--- /dev/null
+.\" 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.