NAME
Data::Focus::LensTester - tester for Lens implementations
SYNOPSIS
use Test::More;
use Data::Focus::LensTester;
use Data::Focus::Lens::HashArray::Index;
my $tester = Data::Focus::LensTester->new(
test_whole => sub { is_deeply($_[0], $_[1]) },
test_part => sub { is($_[0], $_[1]) },
parts => [undef, 1, "str"]
);
my $create_target = sub {
+{ foo => "bar" }
};
my $lens = Data::Focus::Lens::HashArray::Index->new(
index => "foo"
);
$tester->test_lens_laws(
lens => $lens, target => $create_target,
exp_focal_points => 1
);
DESCRIPTION
Data::Focus::LensTester tests some common properties for lenses. They are called the "lens laws".
Concepturally, the lens laws are described as follows.
- set-get law
-
focus( focus($target)->set($lens, $part) )->get($lens) == $part
You get the exact
$part
you just set. - get-set law
-
focus($target)->set( $lens, focus($target)->get($lens) ) == $target
If you put back the part you just got out of the
$target
, it changes nothing. - set-set law
-
focus( focus($target)->set($lens, $part1) )->set($lens, $part2) == focus($target)->set($lens, $part2)
The
$lens
's focal point is consistent, so$part1
is overwritten by$part2
.
Data::Focus::LensTester tests these laws with given set of $part
s.
Tests and Focal Points
Depending on how many focal points the lens creates on the target, test_lens_laws()
method tests the following laws.
- 0 focal point
-
It tests "get-set" and "set-set" laws. "set-get" law cannot be met.
- 1 focal point
-
It tests all three laws.
- more than one focal points
-
It tests "set-get" and "set-set" laws.
In "set-get" law, the
set()
method should set all focal points to the same value.
Exception
Not all lenses meet all the lens laws.
Consider the following code for example.
use strict;
use warnings;
use Data::Dumper;
my $undef;
$undef->[0] = $undef->[0]; ## get and set
print Dumper $undef;
## => $VAR1 = [
## => undef
## => ];
If we think of ->[0]
as a lens, the above example clearly breaks the "get-set" law because of autovivification.
If you expect that kind of behavior, do not use test_lens_laws()
method. Use test_set_get()
etc instead.
CLASS METHODS
$tester = Data::Focus::LensTester->new(%args)
The constructor. Fields in %args
are:
test_whole
=> CODE (mandatory)-
A code-ref that tests if two "whole" data are the same. A whole data is a data whose level of complexity is the same as the target data.
This code-ref is called like:
$test_whole->($whole1, $whole2)
$test_whole
must test equality between$whole1
and$whole2
in a Test::More way. test_part
=> CODE (mandatory)-
A code-ref that tests if two "part" data are the same. A part data is a data that can be included in a whole data.
This code-ref is called like:
$test_part->($part1, $part2)
$test_part
must test equality between$part1
and$part2
in a Test::More way. parts
=> ARRAYREF_OF_PARTS (mandatory)-
List of "part" data used for testing. At least two parts are necessary.
OBJECT METHODS
$tester->test_lens_laws(%args)
Test a Data::Focus::Lens object to see if it follows the lens law. See "Tests and Focal Points".
Fields in %args
are:
lens
=> Data::Focus::Lens object (mandatory)-
The lens to be tested.
target
=> CODE (mandatory)-
A code-ref that returns the target object. It is called without argument.
$target_data = $target->()
The
$target
code-ref must return a brand-new$target_data
object for every call. exp_focal_points
=> INT (mandatory)-
Expected number of focal points the lens creates for the target.
$tester->test_set_get(%args)
$tester->test_get_set(%args)
$tester->test_set_set(%args)
Test individual lens laws. %args
are the same as test_lens_laws()
method.
@parts = $tester->parts
Get the parts passed in new()
method.
AUTHOR
Toshio Ito, <toshioito at cpan.org>