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) == $partYou get the exact
$partyou just set. - get-set law
-
focus($target)->set( $lens, focus($target)->get($lens) ) == $targetIf 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$part1is overwritten by$part2.
Data::Focus::LensTester tests these laws with given set of $parts.
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_wholemust test equality between$whole1and$whole2in 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_partmust test equality between$part1and$part2in 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
$targetcode-ref must return a brand-new$target_dataobject 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>