1Test2::Compare(3) User Contributed Perl Documentation Test2::Compare(3)
2
3
4
6 Test2::Compare - Test2 extension for writing deep comparison tools.
7
9 This library is the driving force behind deep comparison tools such as
10 "Test2::Tools::Compare::is()" and
11 "Test2::Tools::ClassicCompare::is_deeply()".
12
14 package Test2::Tools::MyCheck;
15
16 use Test2::Compare::MyCheck;
17 use Test2::Compare qw/compare/;
18
19 sub MyCheck {
20 my ($got, $exp, $name, @diag) = @_;
21 my $ctx = context();
22
23 my $delta = compare($got, $exp, \&convert);
24
25 if ($delta) {
26 $ctx->fail($name, $delta->diag, @diag);
27 }
28 else {
29 $ctx->ok(1, $name);
30 }
31
32 $ctx->release;
33 return !$delta;
34 }
35
36 sub convert {
37 my $thing = shift;
38 return $thing if blessed($thing) && $thing->isa('Test2::Compare::MyCheck');
39
40 return Test2::Compare::MyCheck->new(stuff => $thing);
41 }
42
43 See Test2::Compare::Base for details about writing a custom check.
44
46 $delta = compare($got, $expect, \&convert)
47 This will compare the structures in $got with those in $expect, The
48 convert sub should convert vanilla structures inside $expect into
49 checks. If there are differences in the structures they will be
50 reported back as an Test2::Compare::Delta tree.
51
52 $build = get_build()
53 Get the current global build, if any.
54
55 push_build($build)
56 Set the current global build.
57
58 $build = pop_build($build)
59 Unset the current global build. This will throw an exception if the
60 build passed in is different from the current global.
61
62 build($class, sub { ... })
63 Run the provided codeblock with a new instance of $class as the
64 current build. Returns the new build.
65
66 $check = convert($thing)
67 $check = convert($thing, $config)
68 This convert function is used by "strict_convert()" and
69 "relaxed_convert()" under the hood. It can also be used as the
70 basis for other convert functions.
71
72 If you want to use it with a custom configuration you should wrap
73 it in another sub like so:
74
75 sub my_convert {
76 my $thing_to_convert = shift;
77 return convert(
78 $thing_to_convert,
79 { ... }
80 );
81 }
82
83 Or the short variant:
84
85 sub my_convert { convert($_[0], { ... }) }
86
87 There are several configuration options, here they are with the
88 default setting listed first:
89
90 implicit_end => 1
91 This option toggles array/hash boundaries. If this is true then
92 no extra hash keys or array indexes will be allowed. This
93 setting effects generated compare objects as well as any passed
94 in.
95
96 use_regex => 1
97 This option toggles regex matching. When true (default) regexes
98 are converted to checks such that values must match the regex.
99 When false regexes will be compared to see if they are
100 identical regexes.
101
102 use_code => 0
103 This option toggles code matching. When false (default)
104 coderefs in structures must be the same coderef as specified.
105 When true coderefs will be run to verify the value being
106 checked.
107
108 $check = strict_convert($thing)
109 Convert $thing to an Test2::Compare::* object. This will behave
110 strictly which means it uses these settings:
111
112 implicit_end => 1
113 Array bounds will be checked when this object is used in a
114 comparison. No unexpected hash keys can be present.
115
116 use_code => 0
117 Sub references will be compared as refs (IE are these sub refs
118 the same ref?)
119
120 use_regex => 0
121 Regexes will be compared directly (IE are the regexes the
122 same?)
123
124 $compare = relaxed_convert($thing)
125 Convert $thing to an Test2::Compare::* object. This will be relaxed
126 which means it uses these settings:
127
128 implicit_end => 0
129 Array bounds will not be checked when this object is used in a
130 comparison. Unexpected hash keys can be present.
131
132 use_code => 1
133 Sub references will be run to verify a value.
134
135 use_regex => 1
136 Values will be checked against any regexes provided.
137
139 use Test2::Compare qw/compare convert/;
140
141 sub my_like($$;$@) {
142 my ($got, $exp, $name, @diag) = @_;
143 my $ctx = context();
144
145 # A custom converter that does the same thing as the one used by like()
146 my $convert = sub {
147 my $thing = shift;
148 return convert(
149 $thing,
150 {
151 implicit_end => 0,
152 use_code => 1,
153 use_regex => 1,
154 }
155 );
156 };
157
158 my $delta = compare($got, $exp, $convert);
159
160 if ($delta) {
161 $ctx->fail($name, $delta->diag, @diag);
162 }
163 else {
164 $ctx->ok(1, $name);
165 }
166
167 $ctx->release;
168 return !$delta;
169 }
170
171 The work of a comparison tool is done by 3 entities:
172
173 compare()
174 The "compare()" function takes the structure you got, the
175 specification you want to check against, and a "\&convert" sub that
176 will convert anything that is not an instance of an
177 Test2::Compare::Base subclass into one.
178
179 This tool will use the "\&convert" function on the specification,
180 and then produce an Test2::Compare::Delta structure that outlines
181 all the ways the structure you got deviates from the specification.
182
183 \&convert
184 Converts anything that is not an instance of an
185 Test2::Compare::Base subclass, and turns it into one. The objects
186 this produces are able to check that a structure matches a
187 specification.
188
189 $delta
190 An instance of Test2::Compare::Delta is ultimately returned. This
191 object represents all the ways in with the structure you got
192 deviated from the specification. The delta is a tree and may
193 contain child deltas for nested structures.
194
195 The delta is capable of rendering itself as a table, use "@lines =
196 $delta->diag" to get the table (lines in @lines will not be
197 terminated with "\n").
198
199 The "convert()" function provided by this package contains all the
200 specification behavior of "like()" and "is()". It is intended to be
201 wrapped in a sub that passes in a configuration hash, which allows you
202 to control the behavior.
203
204 You are free to write your own "$check = compare($thing)" function, it
205 just needs to accept a single argument, and produce a single instance
206 of an Test2::Compare::Base subclass.
207
209 The source code repository for Test2-Suite can be found at
210 https://github.com/Test-More/Test2-Suite/.
211
213 Chad Granum <exodist@cpan.org>
214
216 Chad Granum <exodist@cpan.org>
217
219 Copyright 2018 Chad Granum <exodist@cpan.org>.
220
221 This program is free software; you can redistribute it and/or modify it
222 under the same terms as Perl itself.
223
224 See http://dev.perl.org/licenses/
225
226
227
228perl v5.30.0 2019-07-26 Test2::Compare(3)