File Coverage

blib/lib/Test/Mini/Unit.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1             # Declarative Sugar for Test::Mini.
2             #
3             # Test::Mini::Unit aims to provide a simpler, boilerplate-free environment for
4             # writing new {Test::Mini} test cases. While Test::Mini itself is a fairly
5             # reasonable environment with very little overhead verbosity, the overhead of
6             # creating a new class -- or set of classes -- in Perl can still be a bit more
7             # distracting than you'd really like.
8             #
9             # = Enter Test::Mini::Unit
10             #
11             # At first glance, Test::Mini::Unit provides moderate improvements over the
12             # traditional style, transforming this:
13             #
14             # package t::Test
15             # use base 'Test::Mini::TestCase';
16             # use strict;
17             # use warnings;
18             #
19             # use Test::Mini::Assertions;
20             #
21             # sub setup {
22             # # do something
23             # }
24             #
25             # sub test_some_code {
26             # assert($something_true);
27             # }
28             #
29             # sub teardown {
30             # # undo something
31             # }
32             #
33             # 1;
34             #
35             # Into this:
36             #
37             # use Test::Mini::Unit;
38             #
39             # case t::Test {
40             # setup {
41             # # do something
42             # }
43             #
44             # test some_code {
45             # assert($something_true);
46             # }
47             #
48             # teardown {
49             # # undo something
50             # }
51             # }
52             #
53             # = Advice
54             #
55             # But Test::Mini::Unit really begins to shine as your test cases take on more
56             # complexity. Multiple calls to the test advice methods (+setup+ and
57             # +teardown+) will stack like +BEGIN+ and +END+ blocks, allowing you to
58             # co-locate tests and relevant advice.
59             #
60             # # Traditional
61             # sub setup {
62             # # do a bunch of setup for test_one
63             # # ...
64             # # do a bunch of setup for test_two
65             # # ...
66             # }
67             #
68             # sub test_one { ... }
69             # sub test_two { ... }
70             #
71             # # Test::Mini::Unit
72             # setup { "do setup for test_one" }
73             # sub test_one { ... }
74             #
75             # setup { "do setup for test_two" }
76             # sub test_two { ... }
77             #
78             # = Test-Local Storage
79             #
80             # Per-test local storage is automatically available as +$self+ from all advice
81             # and test blocks.
82             #
83             # setup { $self->{data} = Package->new() }
84             # test data { assert_isa($self->{data}, 'Package') }
85             #
86             # teardown { unlink $self->{tmpfile} }
87             #
88             # = Nesting
89             #
90             # And perhaps most usefully, test cases can be *nested*. Nested test cases
91             # inherit all their outer scope's test advice, allowing you to build richer
92             # tests with far less code.
93             #
94             # case t::IO::Scalar {
95             # setup { $self->{buffer} = IO::Scalar->new() }
96             # test can_read { assert_can($self->{buffer}, 'read') }
97             # test can_write { assert_can($self->{buffer}, 'write') }
98             # test is_empty { assert_empty("@{[$self->{buffer}]}") }
99             #
100             # case AfterWritingString {
101             # setup { $self->{buffer}->print('String!') }
102             # test contents {
103             # assert_equal("@{[$self->{buffer}]}", 'String!');
104             # }
105             # }
106             #
107             # case AfterWritingObject {
108             # setup { $self->{buffer}->print($self) }
109             # test contents {
110             # assert_equal("@{[$self->{buffer}]}", "$self");
111             # }
112             # }
113             # }
114             #
115             # = Sharing Tests...
116             #
117             # In some cases, you may find it useful to reuse the same tests in different
118             # cases. For this purpose, the +shared+ and +reuse+ keywords exist:
119             #
120             # shared BasicBookTests {
121             # test has_pages { ... }
122             # test pages_have_text { ... }
123             # }
124             #
125             # case Book {
126             # reuse BasicBookTests;
127             # }
128             #
129             # case LargePrintBook {
130             # reuse BasicBookTests;
131             # test words_should_be_big { ... }
132             # }
133             #
134             # = ... And Reusing Them
135             #
136             # Groups of shared tests may also be nested inside +case+ blocks, where
137             # they will inherit the namespace of their parent. Since shared tests will
138             # most commonly see reuse inside either the +case+ they're declared in or a
139             # nested case, it's not usually necessary to specify the full package name.
140             # The +reuse+ keyword will try, therefore, to infer the fully qualified
141             # package name from the name it's given. (You can always specify the full name
142             # yourself by prepending '::'.)
143             #
144             # shared CommonTests {
145             # # __PACKAGE__ is 'Nested::CommonTests'
146             # }
147             #
148             # case Nested {
149             # shared CommonTests {
150             # # __PACKAGE__ is 'Nested::CommonTests'
151             # }
152             #
153             # case Deeply {
154             # shared CommonTests {
155             # # __PACKAGE__ is 'Nested::Deeply::CommonTests'
156             # }
157             #
158             # # includes Nested::Deeply::CommonTests
159             # reuse CommonTests;
160             #
161             # # includes Nested::CommonTests
162             # reuse Nested::CommonTests;
163             #
164             # # includes CommonTests
165             # reuse ::CommonTests;
166             # }
167             #
168             # # includes Nested::CommonTests
169             # reuse CommonTests;
170             # }
171             #
172             # = Automatic 'use'
173             #
174             # To automatically use packages inside all your test cases (for example, your
175             # own custom assertions), simply pass the 'with' option to Test::Mini::Unit;
176             # it can accept either a single package name or an array.
177             #
178             # use Test::Mini::Unit (with => [ My::Assertions, My::HelperFuncs ]);
179             #
180             # case t::TestCase {
181             # # My::Assertions and My::HelperFuncs are already imported here.
182             # case Nested {
183             # # In here, too.
184             # }
185             #
186             # shared CommonTests {
187             # # Yup, here too.
188             # }
189             # }
190             #
191             # @see Test::Mini
192             # @author Pieter van de Bruggen
193             package Test::Mini::Unit;
194 11     11   6774 use strict;
  11         18  
  11         386  
195 11     11   58 use warnings;
  11         17  
  11         363  
196 11     11   272 use 5.008;
  11         33  
  11         386  
197              
198 11     11   9904 use version 0.77; our $VERSION = qv("v1.0.3");
  11         25052  
  11         70  
199              
200 11     11   19259 use Test::Mini;
  0            
  0            
201              
202             require Test::Mini::Unit::Sugar::Shared;
203             require Test::Mini::Unit::Sugar::TestCase;
204              
205             # @api private
206             sub import {
207             my ($class, @args) = @_;
208             my $caller = caller();
209              
210             strict->import;
211             warnings->import;
212              
213             Test::Mini::Unit::Sugar::Shared->import(into => $caller, @args);
214             Test::Mini::Unit::Sugar::TestCase->import(into => $caller, @args);
215             }
216              
217             1;