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::HTML' or die;
12}
13
14my $string1   = 'This is a test';
15my $string2   = 'That was a test';
16my $term_diff = '<div class="file"><span class="hunk"><del>This is </del><ins>That was </ins></span><span class="hunk">a test</span></div>';
17my %opts = (
18    STYLE => 'HTML',
19);
20
21# Test scalar refs.
22is word_diff(\$string1, \$string2, \%opts), $term_diff,
23    'Should HTML diff';
24
25# Try code refs.
26is word_diff( sub { \$string1 }, sub { \$string2 } , \%opts ), $term_diff,
27    'Should get same result for code refs';
28
29# Try array refs.
30my $BEGIN_WORD = qr/(?<!\w)(?=\w)/msx;
31my @string1 = split $BEGIN_WORD, $string1;
32my @string2 = split $BEGIN_WORD, $string2;
33is word_diff( \@string1, \@string2, \%opts ), $term_diff,
34    'Should get same result for array refs';
35
36# Mix and match.
37is word_diff( \$string1, \@string2, \%opts ), $term_diff,
38    'Should get same result for a scalar ref and an array ref';
39
40# Try file names.
41my $filename1 = catfile qw(t data left.txt);
42my $filename2 = catfile qw(t data right.txt);
43my $time1     = localtime( (stat $filename1)[9] );
44my $time2     = localtime( (stat $filename2)[9] );
45my $header    = qq{<span class="fileheader">--- $filename1\t$time1\n}
46              . qq{+++ $filename2\t$time2\n</span>};
47
48my $file_diff = qq{<div class="file">$header<span class="hunk">This is a </span>}
49              . qq{<span class="hunk"><del>tst;</del><ins>test.</ins></span>}
50              . qq{<span class="hunk">\n</span>}
51              . qq{<span class="hunk"><del>it </del><ins>It </ins></span>}
52              . qq{<span class="hunk">is only a\ntest. Had </span>}
53              . qq{<span class="hunk"><del>it </del><ins>this </ins></span>}
54              . qq{<span class="hunk">been an\n}
55              . qq{actual diff, the results would\n}
56              . qq{have been output to </span><span class="hunk"><del>HTML</del>}
57              . qq{<ins>the terminal</ins></span>}
58              . qq{<span class="hunk">.\n\nSome string with </span>}
59              . qq{<span class="hunk"><del>funny \$</del><ins>funny \@</ins></span>}
60              . qq{<span class="hunk">\nchars in the end</span>}
61              . qq{<span class="hunk"><del>*</del><ins>?</ins></span>}
62              . qq{<span class="hunk">\n</span></div>};
63
64is word_diff($filename1, $filename2, \%opts), $file_diff,
65    'Diff by file name should include a header';
66
67# No more header after this.
68$file_diff =~ s/\Q$header\E//;
69
70# Try globs.
71local (*FILE1, *FILE2);
72open *FILE1, "<$filename1" or die qq{Cannot open "$filename1": $!};
73open *FILE2, "<$filename2" or die qq{Cannot open "$filename2": $!};
74is word_diff(\*FILE1, \*FILE2, \%opts), $file_diff,
75    'Diff by glob file handles should work';
76close *FILE1;
77close *FILE2;
78
79# Try file handles.
80my $fh1 = IO::File->new($filename1, '<')
81    or die qq{Cannot open "$filename1": $!};
82my $fh2 = IO::File->new($filename2, '<')
83    or die qq{Cannot open "$filename2": $!};
84is word_diff($fh1, $fh2, \%opts), $file_diff,
85    'Diff by IO::File objects should work';
86$fh1->close;
87$fh2->close;
88
89# Try a code refence output handler.
90my $output = '';
91$opts{OUTPUT} = sub { $output .= shift };
92is word_diff(\$string1, \$string2, \%opts ), 2,
93    'Should get a count of 2 hunks with code ref output';
94is $output, $term_diff, 'The code ref should have been called';
95
96# Try a scalar ref output handler.
97$output = '';
98$opts{OUTPUT} = \$output;
99is word_diff(\$string1, \$string2, \%opts), 2,
100    'Should get a count of 2 hunks with scalar ref output';
101is $output, $term_diff, 'The scalar ref should have been appended to';
102
103# Try an array ref output handler.
104my $hunks = [];
105$opts{OUTPUT} = $hunks;
106is word_diff(\$string1, \$string2, \%opts), 2,
107    'Should get a count of 2 hunks with array ref output';
108is join('', @$hunks), $term_diff,
109    'The array ref should have been appended to';
110
111# Try a file handle output handler.
112my $fh = IO::File->new_tmpfile;
113SKIP: {
114    skip 'Cannot create temp filehandle', 2 unless $fh;
115    $opts{OUTPUT} = $fh;
116    is word_diff(\$string1, \$string2, \%opts), 2,
117        'Should get a count of 2 hunks with file handle output';
118    $fh->seek(0, 0);
119    is do { local $/; <$fh>; }, $term_diff,
120        'The file handle should have been written to';
121}
122