-
Notifications
You must be signed in to change notification settings - Fork 87
/
OnlyOnePlan.pm
126 lines (74 loc) · 2.42 KB
/
OnlyOnePlan.pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package TB2::OnlyOnePlan;
use TB2::Mouse;
with 'TB2::EventHandler';
our $VERSION = '2.00_07';
$VERSION = eval $VERSION; ## no critic (BuiltinFunctions::ProhibitStringyEval)
use Carp;
=head1 NAME
TB2::OnlyOnePlan - Enforces there being only one plan per test
=head1 SYNOPSIS
# Add an instance of this to the TestState to enforce plans
use TB2::OnlyOnePlan;
$test_state->add_early_handlers( TB2::OnlyOnePlan->new );
=head1 DESCRIPTION
This is a L<TB2::EventHandler> which enforces there being
only one plan issued per test.
There are exceptions...
=head3 subtests have their own plan
Subtests must have their own plan, so that is allowed.
=head3 Multiple "no_plan"s are allowed
There's no harm in setting "no_plan" multiple times. This
specifically allows...
use Test::More "no_plan";
...test test test...
done_testing();
=head3 Setting a fixed plan is allowed after a "no_plan"
There is no harm in raising the specificity of the plan. This
specifically allows...
use Test::More "no_plan";
...test test test...
done_testing(5);
=head3 Setting a fixed plan the same as the existing fixed plan.
This specificially allows redundant planning...
use Test::More tests => 3;
pass("One");
pass("Two");
pass("Three");
done_testing(3);
=cut
has existing_plan =>
is => 'rw',
isa => 'Object',
;
sub handle_set_plan {
my $self = shift;
my $event = shift;
$self->already_saw_plan($event) if $self->existing_plan;
$self->existing_plan($event);
return;
}
sub already_saw_plan {
my $self = shift;
my $new_plan = shift;
my $existing_plan = $self->existing_plan;
return if $existing_plan->no_plan &&
( $new_plan->no_plan || $new_plan->asserts_expected );
my $asserts_expected = $existing_plan->asserts_expected;
return if $asserts_expected && $asserts_expected == $new_plan->asserts_expected;
my $error = "Tried to set a plan" . $self->_plan_location($new_plan);
$error .= ", but a plan was already set" . $self->_plan_location($existing_plan);
die "$error.\n";
}
sub _plan_location {
my $self = shift;
my $plan = shift;
my $file = $plan->file;
my $line = $plan->line;
my $location = '';
$location .= " at $file" if defined $file;
$location .= " line $line" if defined $line;
return $location;
}
__PACKAGE__->meta->make_immutable();
no TB2::Mouse;
1;