1#!/usr/bin/perl -w
2
3use strict;
4use Test::More tests => 17;
5use Term::ANSIColor qw(:constants);
6use File::Spec::Functions qw(catfile);
7use IO::File;
8
9BEGIN {
10    use_ok 'Text::WordDiff'            or die;
11    use_ok 'Text::WordDiff::ANSIColor' or die;
12}
13
14use constant STRIKETHROUGH => Text::WordDiff::ANSIColor::STRIKETHROUGH();
15
16my $string1 = 'This is a test';
17my $string2 = 'That was a test';
18my $term_diff = BOLD . RED . STRIKETHROUGH . 'This is ' . RESET
19              . BOLD . GREEN . UNDERLINE . 'That was ' . RESET
20              . 'a test';
21
22# Test scalar refs.
23is word_diff(\$string1, \$string2), $term_diff,
24    'Should get a term diff by default';
25
26# Try code refs.
27is word_diff( sub { \$string1 }, sub { \$string2 } ), $term_diff,
28    'Should get same result for code refs';
29
30# Try array refs.
31my $BEGIN_WORD = qr/(?<!\w)(?=\w)/msx;
32my @string1 = split $BEGIN_WORD, $string1;
33my @string2 = split $BEGIN_WORD, $string2;
34is word_diff( \@string1, \@string2 ), $term_diff,
35    'Should get same result for array refs';
36
37# Mix and match.
38is word_diff( \$string1, \@string2 ), $term_diff,
39    'Should get same result for a scalar ref and an array ref';
40
41# Try file names.
42my $filename1 = catfile qw(t data left.txt);
43my $filename2 = catfile qw(t data right.txt);
44my $time1     = localtime( (stat $filename1)[9] );
45my $time2     = localtime( (stat $filename2)[9] );
46my $header    = "--- $filename1\t$time1\n+++ $filename2\t$time2\n";
47
48my $file_diff = 'This is a ' . BOLD . RED . STRIKETHROUGH . "tst;"
49              . RESET . BOLD . GREEN . UNDERLINE . "test." . RESET . "\n"
50              . BOLD . RED . STRIKETHROUGH . "it " . RESET 
51              . BOLD . GREEN . UNDERLINE . "It " . RESET . "is only a\n"
52              . 'test. Had ' . BOLD . RED . STRIKETHROUGH . 'it ' . RESET
53              . BOLD . GREEN . UNDERLINE . 'this ' . RESET . "been an\n"
54              . "actual diff, the results would\n"
55              . 'have been output to ' . BOLD . RED . STRIKETHROUGH . "HTML"
56              . RESET . BOLD . GREEN . UNDERLINE . "the terminal" . RESET . ".\n\n"
57              . 'Some string with ' . BOLD . RED . STRIKETHROUGH . 'funny $'
58              . RESET . BOLD . GREEN . UNDERLINE . 'funny @' . RESET . "\n"
59              . 'chars in the end' . BOLD . RED . STRIKETHROUGH . '*'
60              . RESET . BOLD . GREEN . UNDERLINE . '?' . RESET . "\n";
61
62is word_diff($filename1, $filename2), $header . $file_diff,
63    'Diff by file name should include a header';
64
65# Try globs.
66local (*FILE1, *FILE2);
67open *FILE1, "<$filename1" or die qq{Cannot open "$filename1": $!};
68open *FILE2, "<$filename2" or die qq{Cannot open "$filename2": $!};
69is word_diff(\*FILE1, \*FILE2), $file_diff,
70    'Diff by glob file handles should work';
71close *FILE1;
72close *FILE2;
73
74# Try file handles.
75my $fh1 = IO::File->new($filename1, '<')
76    or die qq{Cannot open "$filename1": $!};
77my $fh2 = IO::File->new($filename2, '<')
78    or die qq{Cannot open "$filename2": $!};
79is word_diff($fh1, $fh2), $file_diff,
80    'Diff by IO::File objects should work';
81$fh1->close;
82$fh2->close;
83
84# Try a code refence output handler.
85my $output = '';
86is word_diff(\$string1, \$string2, { OUTPUT => sub { $output .= shift } } ),
87    2, 'Should get a count of 2 hunks with code ref output';
88is $output, $term_diff, 'The code ref should have been called';
89
90# Try a scalar ref output handler.
91$output = '';
92is word_diff(\$string1, \$string2, { OUTPUT => \$output } ),
93    2, 'Should get a count of 2 hunks with scalar ref output';
94is $output, $term_diff, 'The scalar ref should have been appended to';
95
96# Try an array ref output handler.
97my $hunks = [];
98is word_diff(\$string1, \$string2, { OUTPUT => $hunks } ),
99    2, 'Should get a count of 2 hunks with array ref output';
100is join('', @$hunks), $term_diff,
101    'The array ref should have been appended to';
102
103# Try a file handle output handler.
104my $fh = IO::File->new_tmpfile;
105SKIP: {
106    skip 'Cannot create temp filehandle', 2 unless $fh;
107    is word_diff(\$string1, \$string2, { OUTPUT => $fh } ),
108        2, 'Should get a count of 2 hunks with file handle output';
109    $fh->seek(0, 0);
110    is do { local $/; <$fh>; }, $term_diff,
111        'The file handle should have been written to';
112}
113