NAME

Test::Stream::Compare - Tools for comparing data structures.

EXPERIMENTAL CODE WARNING

This is an experimental release! Test-Stream, and all its components are still in an experimental phase. This dist has been released to cpan in order to allow testers and early adopters the chance to write experimental new tools with it, or to add experimental support for it into old tools.

PLEASE DO NOT COMPLETELY CONVERT OLD TOOLS YET. This experimental release is very likely to see a lot of code churn. API's may break at any time. Test-Stream should NOT be depended on by any toolchain level tools until the experimental phase is over.

DESCRIPTION

This library is the driving force behind is(). The library is the base class for several comparison classes that allow for deep structure comparisons.

SYNOPSIS

FOR COMPARISON CLASSES

package Test::Stream::Compare::MyCheck;
use strict;
use warnings;

use Test::Stream::Compare;
use Test::Stream::HashBase(
    base => 'Test::Stream::Compare',
    accessors => [qw/stuff/],
);

sub name { 'STUFF' }

sub operator {
    my $self = shift;
    my ($got) = @_;
    return 'eq';
}

sub verify {
    my $self = shift;
    my $params = @_;

    # Always check if $got even exists, this will be false if no value at
    # all was recieved. (as opposed to a $got of 'undef' or '0' which are
    # valid meaning this field will be true).
    return 0 unless $params{exists};

    my $got = $params{got};

    return $got eq $self->stuff;
}

FOR PLUGINS

package Test::Stream::Plugin::MyCheck;

use Test::Stream::Compare::MyCheck;

use Test::Stream::Compare qw/compare get_build push_build pop_build build/;

sub MyCheck {
    my ($got, $exp, $name, @diag) = @_;
    my $ctx = context();

    my $delta = compare($got, $exp, \&convert);

    if ($delta) {
        $ctx->ok(0, $name, [$delta->table, @diag]);
    }
    else {
        $ctx->ok(1, $name);
    }

    $ctx->release;
    return !$delta;
}

sub convert {
    my $thing = shift;
    return $thing if blessed($thing) && $thing->isa('Test::Stream::Compare::MyCheck');

    return Test::Stream::Compare::MyCheck->new(stuff => $thing);
}

EXPORTS

$delta = compare($got, $expect, \&convert)

This will compare the structures in $got with those in $expect, The convert sub should convert vanilla structures inside $expect into checks. If there are differences in the structures they will be reported back as an Test::Stream::Delta tree.

$build = get_build()

Get the current global build, if any.

push_build($build)

Set the current global build.

$build = pop_build($build)

Unset the current global build. This will throw an exception if the build passed in is different from the current global.

build($class, sub { ... })

Run the provided codeblock with a new instance of $class as the current build. Returns the new build.

METHODS

Some of these must be overriden, others can be.

$dclass = $check->delta_class

Returns the delta subclass that should be used. By default Test::Stream::Delta is used.

@deltas = $check->deltas(id => $id, exists => $bool, got => $got, convert => \&convert, seen => \%seen)

Should return child deltas.

@lines = $check->got_lines($got)

This is your chance to provide line numbers for errors in the $got structure.

$op = $check->operator()
$op = $check->operator($got)

Returns the operator that was used to compare the check with the recieved data in $got. If there was no value for got then there will be no arguments, undef will only be an argument if undef was seen in $got, this is how you can tell the difference between a missing value and an undefined one.

$bool = $check->verify(id => $id, exists => $bool, got => $got, convert => \&convert, seen => \%seen)

Return true if there is a shallow match, that is both items are arrayrefs, both items are the same string or same number, etc. This should not look deep, deep checks are done in $check->deltas().

$name = $check->name

Get the name of the check.

$display = $check->render

What should be displayed in a table for this check, usually the name or value.

$delta = $check->run(id => $id, exists => $bool, got => $got, convert => \&convert, seen => \%seen)

This is where the checking is done, first a shallow check using $check->verify, then checking $check->deltas(). \%seen is used to prevent cycles.

SOURCE

The source code repository for Test::Stream can be found at http://github.com/Test-More/Test-Stream/.

MAINTAINERS

Chad Granum <exodist@cpan.org>

AUTHORS

Chad Granum <exodist@cpan.org>

COPYRIGHT

Copyright 2015 Chad Granum <exodist7@gmail.com>.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

See http://www.perl.com/perl/misc/Artistic.html