Test::InDomain - Testing deep datastructures against data domains


  use Test::More;
  use Test::InDomain;
  plan tests => $number_of_tests;

  in_domain $v1, List(-all => Int(-min => 0), -size => [5, 10]),
                 "5 to 10 positive integers";

  my $expr_domain;
  $expr_domain = One_of(Num, Struct(operator => String(qr(^[-+*/]$)),
                                    left     => sub {$expr_domain},
                                    right    => sub {$expr_domain}));
  in_domain $v2, $expr_domain, "binary expression tree";

  in_domain $v3, Struct(data    => Defined,
                        printer => Obj(-can => 'print')),
                 "struct with data hash and printer object";


This module is a complement to Test::Simple or Test::More (or any other testing module based on Test::Builder). It adds the function in_domain to your panoply of testing tools; that function uses the functionalities of Data::Domain to check deep datastructures and produce detailed reports about where the data differs from the expectations.

The synopsis above is just an appetizer : many more kinds of comparisons can be performed; see Data::Domain for details.


Exports from Test::InDomain


  in_domain $data, $domain, $test_name;

Calls $domain->inspect($data) to check if the data belongs to the domain. The third argument $test_name is optional; if present, it will be printed together with the test result.

If the test fails, the structured error messages issued from Data::Domain are printed as a diagnostic.


  not_in_domain $data, $domain, $test_name, $want_explanation;

This test succeeds if $domain->inspect($data) fails, i.e. the data is not in the domain. By default the error messages will not be printed (since the error was expected, the messages are not interesting!); however, if the fourth argument $want_explanation is true, then the messages will be printed as a note (so they won't be seen when the test in run in a harness, but will be visible in the verbose TAP stream).

Exports from Data::Domain

By default, all symbols from Data::Domain will be exported into the caller's namespace : Int, String, List, Struct, True, Defined, Obj, etc. However it is also possible to explicitly state what to import, and even to rename the imported symbols through Sub::Exporter options, like for example :

  use Test::InDomain -constructors => {-prefix => "dom_"};

To achieve this, the import list passed to Test::InDomain is transmitted directly to Data::Domain; by contrast, functions specific to Test::InDomain, namely in_domain and not_in_domain, are not affected by the import list and will be exported in any case.


Other ways to perform deep comparisons : "is_deeply" in Test::More, Test::Deep.


Laurent Dami, <dami at>


Please report any bugs or feature requests to bug-test-indomain at, or through the web interface at I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.


Copyright 2012 Laurent Dami.

This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.

See for more information.