Test-Snapshot-0.06/0000755000076400007640000000000013243675034012710 5ustar useruserTest-Snapshot-0.06/META.json0000644000076400007640000000353213243675034014334 0ustar useruser{ "abstract" : "test against data stored in automatically-named file", "author" : [ "Ed J " ], "dynamic_config" : 0, "generated_by" : "ExtUtils::MakeMaker version 7.3, CPAN::Meta::Converter version 2.150005", "license" : [ "artistic_2" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : 2 }, "name" : "Test-Snapshot", "no_index" : { "directory" : [ "t", "inc" ] }, "prereqs" : { "build" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "configure" : { "requires" : { "ExtUtils::MakeMaker" : "7.04" } }, "develop" : { "requires" : { "Pod::Markdown" : "0", "Test::CheckManifest" : "0.9", "Test::Pod" : "1.22" } }, "runtime" : { "requires" : { "Exporter" : "5.57", "File::Path" : "2.07", "Test2::API" : "0", "Test::More" : "0.96", "Text::Diff" : "0", "perl" : "5.008003" } }, "test" : { "requires" : { "App::Prove" : "0", "Capture::Tiny" : "0", "Test2::API" : "0", "Test::More" : "0.96", "Text::Diff" : "0" } } }, "release_status" : "stable", "resources" : { "bugtracker" : { "web" : "https://github.com/mohawk2/Test-Snapshot/issues" }, "license" : [ "http://dev.perl.org/licenses/" ], "repository" : { "type" : "git", "web" : "https://github.com/mohawk2/Test-Snapshot" }, "x_IRC" : "irc://irc.perl.org/#graphql-perl" }, "version" : "0.06", "x_serialization_backend" : "JSON::PP version 2.97000" } Test-Snapshot-0.06/MANIFEST0000644000076400007640000000055413243675034014045 0ustar useruserChanges lib/Test/Snapshot.pm Makefile.PL MANIFEST This list of files README.md t/00-report-prereqs.t t/diff.t t/errors.t t/snapshot.t t/snapshots/errors_t/error t/undef.t xt/manifest.t xt/pod.t META.yml Module YAML meta-data (added by MakeMaker) META.json Module JSON meta-data (added by MakeMaker) Test-Snapshot-0.06/README.md0000644000076400007640000000550513243674715014201 0ustar useruser# NAME Test::Snapshot - test against data stored in automatically-named file # PROJECT STATUS | OS | Build status | |:-------:|--------------:| | Linux | [![Build Status](https://travis-ci.org/mohawk2/Test-Snapshot.svg?branch=master)](https://travis-ci.org/mohawk2/Test-Snapshot) | [![CPAN version](https://badge.fury.io/pl/Test-Snapshot.svg)](https://metacpan.org/pod/Test::Snapshot) # SYNOPSIS use Test::Snapshot; my $got = function_generating_data(); is_deeply_snapshot $got, 'test description'; # could also be in a subtest # command line: TEST_SNAPSHOT_UPDATE=1 prove -lr t # or TEST_SNAPSHOT_UPDATE=1 make test # if your code means the expected data should change, then inspect with git diff -w # DESCRIPTION Not connected with [Test::Snapshots](https://metacpan.org/pod/Test::Snapshots), which is based on a similar concept but for running executables. Implements a function to automate the storing and updating of expected test outputs. This is based on the idea known in frontend development circles as "snapshot testing", hence the module name. These snapshots will be stored in files whose names are automatically generated from: - the test filename (`$0`) - any subtests' names surrounding and including this one - the test description if any If that file is not present, it will be treated as though it contains an `undef`. # FUNCTIONS ## is\_deeply\_snapshot Exported by default. Takes two mandatory arguments: - The "got" data (mandatory), a scalar which might be a reference. It will be passed to ["is\_deeply" in Test::More](https://metacpan.org/pod/Test::More#is_deeply) to be compared to the snapshotted data. - A text description of this test (mandatory). It will be used for reporting results, but also to derive the filename in which the "expected" data is stored. Will return the truth value of whether the test passed this time - see below for automatic updating of "expected" data. # ENVIRONMENT To have this module automatically update its "expected" data, set environment variable `TEST_SNAPSHOT_UPDATE` to a true value. If the got and expected data do not match, a test failure will be reported, but the "expected" data will be updated anyway. This means it is safe to always have the variable set to a true value, so long as you are using source control (you _are_ using source control, right?) and check your diffs before committing. # FILE FORMAT The "expected" data will be stored in a format generated by ["Dumper" in Data::Dumper](https://metacpan.org/pod/Data::Dumper#Dumper), with these values set to true, to maximise readability (and to minimise diffs) of the stored data: - Sortkeys - Indent - Terse # AUTHOR Ed J, `` # LICENSE Copyright (C) Ed J This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. Test-Snapshot-0.06/META.yml0000644000076400007640000000172313243675034014164 0ustar useruser--- abstract: 'test against data stored in automatically-named file' author: - 'Ed J ' build_requires: App::Prove: '0' Capture::Tiny: '0' ExtUtils::MakeMaker: '0' Test2::API: '0' Test::More: '0.96' Text::Diff: '0' configure_requires: ExtUtils::MakeMaker: '7.04' dynamic_config: 0 generated_by: 'ExtUtils::MakeMaker version 7.3, CPAN::Meta::Converter version 2.150005' license: artistic_2 meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: Test-Snapshot no_index: directory: - t - inc requires: Exporter: '5.57' File::Path: '2.07' Test2::API: '0' Test::More: '0.96' Text::Diff: '0' perl: '5.008003' resources: IRC: irc://irc.perl.org/#graphql-perl bugtracker: https://github.com/mohawk2/Test-Snapshot/issues license: http://dev.perl.org/licenses/ repository: https://github.com/mohawk2/Test-Snapshot version: '0.06' x_serialization_backend: 'CPAN::Meta::YAML version 0.018' Test-Snapshot-0.06/xt/0000755000076400007640000000000013243675034013343 5ustar useruserTest-Snapshot-0.06/xt/pod.t0000644000076400007640000000052313224311641014300 0ustar useruser#!perl -T use strict; use warnings; use Test::More; unless ( $ENV{RELEASE_TESTING} ) { plan( skip_all => "Author tests not required for installation" ); } # Ensure a recent version of Test::Pod my $min_tp = 1.22; eval "use Test::Pod $min_tp"; plan skip_all => "Test::Pod $min_tp required for testing POD" if $@; all_pod_files_ok(); Test-Snapshot-0.06/xt/manifest.t0000644000076400007640000000045513224311641015330 0ustar useruser#!perl -T use strict; use warnings; use Test::More; unless ( $ENV{RELEASE_TESTING} ) { plan( skip_all => "Author tests not required for installation" ); } my $min_tcm = 0.9; eval "use Test::CheckManifest $min_tcm"; plan skip_all => "Test::CheckManifest $min_tcm required" if $@; ok_manifest(); Test-Snapshot-0.06/Changes0000644000076400007640000000100013243675006014171 0ustar useruserRevision history for Perl extension Test-Snapshot 0.06 Fri Feb 23 02:17:16 GMT 2018 - localise $@ to avoid spurious diag - thanks @nohuhu 0.05 Fri Jan 26 22:53:04 GMT 2018 - generate diff rather than full dump on test-fail 0.04 Thu Jan 11 01:55:54 GMT 2018 - instead use App::Prove 0.03 Mon Jan 8 10:28:49 GMT 2018 - use perl -S to find correct prove in test 0.02 Sun Jan 7 05:57:36 GMT 2018 - allow snapshot filenames keep digits, dashes, letters 0.01 Sun Jan 7 03:27:51 GMT 2018 - first version Test-Snapshot-0.06/lib/0000755000076400007640000000000013243675034013456 5ustar useruserTest-Snapshot-0.06/lib/Test/0000755000076400007640000000000013243675034014375 5ustar useruserTest-Snapshot-0.06/lib/Test/Snapshot.pm0000644000076400007640000001214013243674634016535 0ustar useruserpackage Test::Snapshot; use 5.008001; use strict; use warnings; require Test::More; use Test2::API qw(context); use Exporter 'import'; require Carp; require File::Spec; require File::Path; require File::Basename; require Data::Dumper; use Text::Diff; our $VERSION = "0.06"; our @EXPORT = qw(is_deeply_snapshot); sub is_deeply_snapshot { my ($got, $description) = @_; my $expected = "undef\n"; my $filename = _get_filename($description); if (-f $filename) { no strict; local $@; $expected = eval { _read_file($filename) }; Test::More::diag("Error in snapshot '$filename': $@") if $@; } else { Test::More::diag("No snapshot filename '$filename' found"); } my $dumper = Data::Dumper->new([$got]); $dumper->Indent(1)->Terse(1); $dumper->Sortkeys(1) if $dumper->can("Sortkeys"); my $dump = $dumper->Dump; my $result = $dump eq $expected; local $Test::Builder::Level = $Test::Builder::Level + 1; if ($result) { Test::More::pass($description); } else { Test::More::fail($description); Test::More::diag(diff \$expected, \$dump); if ($ENV{TEST_SNAPSHOT_UPDATE}) { _make_dir_for($filename); _write_file($filename, $dump); } } $result; } sub _get_filename { my ($description) = @_; Carp::croak("No description given") if !defined $description; my $ctx = context(); my ($topfile, @stack) = map $_->get_meta('Test::Builder')->{Name}, $ctx->stack->all; $ctx->release; push @stack, $description if defined $description; # turn the test-file location into its sibling called "snapshots/$basename" my ($v, $d, $f) = File::Spec->splitpath(File::Spec->rel2abs($topfile)); unshift @stack, $f; @stack = map { my $t = $_; $t =~ s#[^a-z\-0-9]+#_#gi; $t } @stack; my $basename = pop @stack; File::Spec->catpath( $v, File::Spec->catdir($d, 'snapshots', @stack), $basename, ); } sub _read_file { my ($filename) = @_; local $/; open my $fh, '<', $filename or die "$filename: $!\n"; <$fh>; } sub _write_file { my ($filename, $data) = @_; open my $fh, '>', $filename or die "$filename: $!\n"; print $fh $data or die "$filename: $!\n"; } sub _make_dir_for { my ($filename) = @_; my $dir = File::Basename::dirname($filename); File::Path::make_path($dir); # will croak if fails } =encoding utf-8 =head1 NAME Test::Snapshot - test against data stored in automatically-named file =begin markdown # PROJECT STATUS | OS | Build status | |:-------:|--------------:| | Linux | [![Build Status](https://travis-ci.org/mohawk2/Test-Snapshot.svg?branch=master)](https://travis-ci.org/mohawk2/Test-Snapshot) | [![CPAN version](https://badge.fury.io/pl/Test-Snapshot.svg)](https://metacpan.org/pod/Test::Snapshot) =end markdown =head1 SYNOPSIS use Test::Snapshot; my $got = function_generating_data(); is_deeply_snapshot $got, 'test description'; # could also be in a subtest # command line: TEST_SNAPSHOT_UPDATE=1 prove -lr t # or TEST_SNAPSHOT_UPDATE=1 make test # if your code means the expected data should change, then inspect with git diff -w =head1 DESCRIPTION Not connected with L, which is based on a similar concept but for running executables. Implements a function to automate the storing and updating of expected test outputs. This is based on the idea known in frontend development circles as "snapshot testing", hence the module name. These snapshots will be stored in files whose names are automatically generated from: =over =item the test filename (C<$0>) =item any subtests' names surrounding and including this one =item the test description if any =back If that file is not present, it will be treated as though it contains an C. =head1 FUNCTIONS =head2 is_deeply_snapshot Exported by default. Takes two mandatory arguments: =over =item The "got" data (mandatory), a scalar which might be a reference. It will be passed to L to be compared to the snapshotted data. =item A text description of this test (mandatory). It will be used for reporting results, but also to derive the filename in which the "expected" data is stored. =back Will return the truth value of whether the test passed this time - see below for automatic updating of "expected" data. =head1 ENVIRONMENT To have this module automatically update its "expected" data, set environment variable C to a true value. If the got and expected data do not match, a test failure will be reported, but the "expected" data will be updated anyway. This means it is safe to always have the variable set to a true value, so long as you are using source control (you I using source control, right?) and check your diffs before committing. =head1 FILE FORMAT The "expected" data will be stored in a format generated by L, with these values set to true, to maximise readability (and to minimise diffs) of the stored data: =over =item Sortkeys =item Indent =item Terse =back =head1 AUTHOR Ed J, C<< >> =head1 LICENSE Copyright (C) Ed J This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1; Test-Snapshot-0.06/Makefile.PL0000644000076400007640000000317113232753620014660 0ustar useruseruse 5.008001; use strict; use warnings; use ExtUtils::MakeMaker; WriteMakefile( NAME => 'Test::Snapshot', AUTHOR => q{Ed J }, VERSION_FROM => 'lib/Test/Snapshot.pm', ABSTRACT_FROM => 'lib/Test/Snapshot.pm', LICENSE => 'artistic_2', MIN_PERL_VERSION => '5.008003', # first with right Exporter CONFIGURE_REQUIRES => { 'ExtUtils::MakeMaker' => '7.04', }, TEST_REQUIRES => { 'Test::More' => '0.96', # subtest does done_testing 'Test2::API' => '0', 'Capture::Tiny' => 0, 'App::Prove' => 0, 'Text::Diff' => '0', }, PREREQ_PM => { 'Test::More' => '0.96', # subtest does done_testing 'Test2::API' => '0', 'Exporter' => '5.57', # exported "import" 'File::Path' => '2.07', # make_path 'Text::Diff' => '0', }, clean => { FILES => 'Test-Snapshot-*' }, META_MERGE => { "meta-spec" => { version => 2 }, dynamic_config => 0, resources => { x_IRC => 'irc://irc.perl.org/#graphql-perl', repository => { type => 'git', url => 'git@github.com:mohawk2/Test-Snapshot.git', web => 'https://github.com/mohawk2/Test-Snapshot', }, bugtracker => { web => 'https://github.com/mohawk2/Test-Snapshot/issues', }, license => [ 'http://dev.perl.org/licenses/' ], }, prereqs => { develop => { requires => { 'Test::CheckManifest' => '0.9', 'Test::Pod' => '1.22', 'Pod::Markdown' => 0, }, }, }, }, ); sub MY::postamble { <\$\@ EOF } Test-Snapshot-0.06/t/0000755000076400007640000000000013243675034013153 5ustar useruserTest-Snapshot-0.06/t/snapshot.t0000644000076400007640000000222013225452251015165 0ustar useruseruse Test::More 0.96; use Test::Snapshot; use File::Temp qw/ tempfile tempdir /; use Capture::Tiny qw(capture); use App::Prove; sub tempcopy { my ($text, $dir) = @_; my ($tfh, $filename) = tempfile( DIR => $dir ); print $tfh $text; close $tfh; $filename; } $ENV{TEST_SNAPSHOT_UPDATE} = 0; # override to ensure known value my $dir = tempdir( CLEANUP => 1 ); my $filename = tempcopy(<<'EOF', $dir); use Test::More 0.96; use Test::Snapshot; subtest 'subtestname' => sub { is_deeply_snapshot 'just some text', 'subtest desc'; }; is_deeply_snapshot { message => 'output' }, 'desc'; done_testing; EOF sub do_test { my ($filename, $update, $expect, $description) = @_; my ($out, $err, $exit) = capture { local $ENV{TEST_SNAPSHOT_UPDATE} = $update; my $app = App::Prove->new; $app->process_args(qw(-b), $filename); $app->run ? 0 : 1; }; is $exit, $expect, $description or diag 'Output was: ', $out, 'Error was: ', $err; } do_test($filename, '', 1, 'fails first time'); do_test($filename, 1, 1, 'fails second time, snapshots were not created'); do_test($filename, 1, 0, 'works third time, snapshots were created'); done_testing; Test-Snapshot-0.06/t/errors.t0000644000076400007640000000067113243674624014664 0ustar useruseruse Test::More 0.96; use Test::Snapshot; use strict; use warnings; $ENV{TEST_SNAPSHOT_UPDATE} = 0; # override to ensure known value my $errdiag; { no strict 'refs'; no warnings 'redefine'; *{"Test::More::diag"} = sub { $errdiag = shift; } } my $xcpt = 'blergo mymse throbbozongo'; $@ = $xcpt; is_deeply_snapshot('foo bar', 'error'); unlike $errdiag, qr/$xcpt/, "exception not passed to diag()"; done_testing; Test-Snapshot-0.06/t/undef.t0000644000076400007640000000162613232753472014447 0ustar useruseruse Test::More 0.96; use Test::Snapshot; use File::Temp qw/ tempfile tempdir /; use Capture::Tiny qw(capture); use App::Prove; sub tempcopy { my ($text, $dir) = @_; my ($tfh, $filename) = tempfile( DIR => $dir ); print $tfh $text; close $tfh; $filename; } $ENV{TEST_SNAPSHOT_UPDATE} = 0; # override to ensure known value my $dir = tempdir( CLEANUP => 1 ); my $filename = tempcopy(<<'EOF', $dir); use Test::More 0.96; use Test::Snapshot; is_deeply_snapshot undef, 'desc'; done_testing; EOF sub do_test { my ($filename, $update, $expect, $description) = @_; my ($out, $err, $exit) = capture { local $ENV{TEST_SNAPSHOT_UPDATE} = $update; my $app = App::Prove->new; $app->process_args(qw(-b), $filename); $app->run ? 0 : 1; }; is $exit, $expect, $description or diag 'Output was: ', $out, 'Error was: ', $err; } do_test($filename, '', 0, 'no snapshot = undef'); done_testing; Test-Snapshot-0.06/t/snapshots/0000755000076400007640000000000013243675034015175 5ustar useruserTest-Snapshot-0.06/t/snapshots/errors_t/0000755000076400007640000000000013243675034017034 5ustar useruserTest-Snapshot-0.06/t/snapshots/errors_t/error0000644000076400007640000000001213243674624020105 0ustar useruser'foo bar' Test-Snapshot-0.06/t/00-report-prereqs.t0000644000076400007640000001350613224312106016537 0ustar useruser#!perl use strict; use warnings; # This test was generated by Dist::Zilla::Plugin::Test::ReportPrereqs 0.020 # THEN modified with more info by Ed J for PDL project use Test::More tests => 1; use ExtUtils::MakeMaker; use File::Spec; # from $version::LAX my $lax_version_re = qr/(?: undef | (?: (?:[0-9]+) (?: \. | (?:\.[0-9]+) (?:_[0-9]+)? )? | (?:\.[0-9]+) (?:_[0-9]+)? ) | (?: v (?:[0-9]+) (?: (?:\.[0-9]+)+ (?:_[0-9]+)? )? | (?:[0-9]+)? (?:\.[0-9]+){2,} (?:_[0-9]+)? ) )/x; # hide optional CPAN::Meta modules from prereq scanner # and check if they are available my $cpan_meta = "CPAN::Meta"; my $cpan_meta_pre = "CPAN::Meta::Prereqs"; my $HAS_CPAN_META = eval "require $cpan_meta; $cpan_meta->VERSION('2.120900')" && eval "require $cpan_meta_pre"; ## no critic # Verify requirements? my $DO_VERIFY_PREREQS = 1; sub _max { my $max = shift; $max = ( $_ > $max ) ? $_ : $max for @_; return $max; } sub _merge_prereqs { my ($collector, $prereqs) = @_; # CPAN::Meta::Prereqs object if (ref $collector eq $cpan_meta_pre) { return $collector->with_merged_prereqs( CPAN::Meta::Prereqs->new( $prereqs ) ); } # Raw hashrefs for my $phase ( keys %$prereqs ) { for my $type ( keys %{ $prereqs->{$phase} } ) { for my $module ( keys %{ $prereqs->{$phase}{$type} } ) { $collector->{$phase}{$type}{$module} = $prereqs->{$phase}{$type}{$module}; } } } return $collector; } my @include = qw( ); my @exclude = qw( ); # Add static prereqs to the included modules list my $static_prereqs = do 't/00-report-prereqs.dd'; # Merge all prereqs (either with ::Prereqs or a hashref) my $full_prereqs = _merge_prereqs( ( $HAS_CPAN_META ? $cpan_meta_pre->new : {} ), $static_prereqs ); # Add dynamic prereqs to the included modules list (if we can) my ($source) = grep { -f } 'MYMETA.json', 'MYMETA.yml'; if ( $source && $HAS_CPAN_META ) { if ( my $meta = eval { CPAN::Meta->load_file($source) } ) { $full_prereqs = _merge_prereqs($full_prereqs, $meta->prereqs); } } else { $source = 'static metadata'; } my @full_reports; my @dep_errors; my $req_hash = $HAS_CPAN_META ? $full_prereqs->as_string_hash : $full_prereqs; # Add static includes into a fake section for my $mod (@include) { $req_hash->{other}{modules}{$mod} = 0; } for my $phase ( qw(configure build test runtime develop other) ) { next unless $req_hash->{$phase}; next if ($phase eq 'develop' and not $ENV{AUTHOR_TESTING}); for my $type ( qw(requires recommends suggests conflicts modules) ) { next unless $req_hash->{$phase}{$type}; my $title = ucfirst($phase).' '.ucfirst($type); my @reports = [qw/Module Want Have Where Howbig/]; for my $mod ( sort keys %{ $req_hash->{$phase}{$type} } ) { next if $mod eq 'perl'; next if grep { $_ eq $mod } @exclude; my $file = $mod; $file =~ s{::}{/}g; $file .= ".pm"; my ($prefix) = grep { -e File::Spec->catfile($_, $file) } @INC; my $want = $req_hash->{$phase}{$type}{$mod}; $want = "undef" unless defined $want; $want = "any" if !$want && $want == 0; my $req_string = $want eq 'any' ? 'any version required' : "version '$want' required"; if ($prefix) { my $filename = File::Spec->catfile($prefix, $file); my $have = MM->parse_version( $filename ); $have = "undef" unless defined $have; push @reports, [$mod, $want, $have, $prefix, (-s $filename)]; if ( $DO_VERIFY_PREREQS && $HAS_CPAN_META && $type eq 'requires' ) { if ( $have !~ /\A$lax_version_re\z/ ) { push @dep_errors, "$mod version '$have' cannot be parsed ($req_string)"; } elsif ( ! $full_prereqs->requirements_for( $phase, $type )->accepts_module( $mod => $have ) ) { push @dep_errors, "$mod version '$have' is not in required range '$want'"; } } } else { push @reports, [$mod, $want, "missing", '', 0]; if ( $DO_VERIFY_PREREQS && $type eq 'requires' ) { push @dep_errors, "$mod is not installed ($req_string)"; } } } if ( @reports ) { push @full_reports, "=== $title ===\n\n"; my $ml = _max( map { length $_->[0] } @reports ); my $wl = _max( map { length $_->[1] } @reports ); my $hl = _max( map { length $_->[2] } @reports ); my $ll = _max( map { length $_->[3] } @reports ); # location my $sl = _max( map { length $_->[4] } @reports ); # size if ($type eq 'modules') { splice @reports, 1, 0, ["-" x $ml, "", "-" x $hl, "-" x $ll, "-" x $sl]; push @full_reports, map { sprintf(" %*s %*s\n", -$ml, $_->[0], $hl, $_->[2]) } @reports; } else { splice @reports, 1, 0, ["-" x $ml, "-" x $wl, "-" x $hl, "-" x $ll, "-" x $sl]; push @full_reports, map { sprintf(" %*s %*s %*s %*s %*s\n", -$ml, $_->[0], $wl, $_->[1], $hl, $_->[2], -$ll, $_->[3], $sl, $_->[4]) } @reports; } push @full_reports, "\n"; } } } if ( @full_reports ) { diag "\nVersions for all modules listed in $source (including optional ones):\n\n", @full_reports; } if ( @dep_errors ) { diag join("\n", "\n*** WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING ***\n", "The following REQUIRED prerequisites were not satisfied:\n", @dep_errors, "\n" ); } pass; # vim: ts=4 sts=4 sw=4 et: Test-Snapshot-0.06/t/diff.t0000644000076400007640000000277513232753620014257 0ustar useruseruse Test::More 0.96; use Test::Snapshot; use File::Temp qw/ tempfile tempdir /; use Capture::Tiny qw(capture); use App::Prove; sub tempcopy { my ($text, $dir) = @_; my ($tfh, $filename) = tempfile( DIR => $dir ); print $tfh $text; close $tfh; $filename; } sub write_file { my ($filename, $data) = @_; open my $fh, '>', $filename or die "$filename: $!"; print $fh $data; } $ENV{TEST_SNAPSHOT_UPDATE} = 0; # override to ensure known value my $dir = tempdir( CLEANUP => 1 ); my $filename = tempcopy(<<'EOF', $dir); use Test::More 0.96; use Test::Snapshot; is_deeply_snapshot { message => 'output' }, 'desc'; done_testing; EOF sub do_test { my ($filename, $update, $expect, $description) = @_; my ($out, $err, $exit) = capture { local $ENV{TEST_SNAPSHOT_UPDATE} = $update; my $app = App::Prove->new; $app->process_args(qw(-b), $filename); $app->run ? 0 : 1; }; is $exit, $expect, $description or diag 'Output was: ', $out, 'Error was: ', $err; ($out, $err); } do_test($filename, 1, 1, 'fails first time, generate snapshots'); write_file($filename, <<'EOF'); use Test::More 0.96; use Test::Snapshot; is_deeply_snapshot { message => 'different' }, 'desc'; done_testing; EOF my ($out, $err) = do_test($filename, 0, 1, 'fails second time, check diffs'); isnt $out, ''; $err =~ s#^.* at .* line \d+\.$##m; is $err, <<'EOF'; # Failed test 'desc' # @@ -1,3 +1,3 @@ # { # - 'message' => 'output' # + 'message' => 'different' # } # Looks like you failed 1 test of 1. EOF done_testing;