1#!perl
2
3BEGIN {
4	if ($] <= 5.010) {
5		print "1..0 # skip this test requires perl 5.010 or greater ($])\n";
6		exit 0;
7	}
8}
9
10use strict;
11use warnings "FATAL" => "all";
12use Text::Tabs;
13
14require bytes;
15
16our $Errors = 0;
17
18our @DATA = (
19    [ # DATALINE #0
20	sub { die "there is no line 0" }
21    ],
22    { # DATALINE #1
23	OLD => { BYTES =>  71, CHARS => 59, CHUNKS => 47, WORDS => 7, TABS => 3 },
24	NEW => { BYTES =>  92, CHARS => 80, CHUNKS => 68, WORDS => 7, TABS => 0 },
25    },
26    { # DATALINE #2
27	OLD => { BYTES =>  45, CHARS => 43, CHUNKS => 41, WORDS => 6, TABS => 3 },
28	NEW => { BYTES =>  65, CHARS => 63, CHUNKS => 61, WORDS => 6, TABS => 0 },
29    },
30    { # DATALINE #3
31	OLD => { BYTES =>  47, CHARS => 45, CHUNKS => 43, WORDS => 7, TABS => 3 },
32	NEW => { BYTES =>  64, CHARS => 62, CHUNKS => 60, WORDS => 7, TABS => 0 },
33    },
34    { # DATALINE #4
35	OLD => { BYTES =>  49, CHARS => 47, CHUNKS => 45, WORDS => 7, TABS => 3 },
36	NEW => { BYTES =>  69, CHARS => 67, CHUNKS => 65, WORDS => 7, TABS => 0 },
37    },
38    { # DATALINE #5
39	OLD => { BYTES =>  83, CHARS => 62, CHUNKS => 41, WORDS => 7, TABS => 4 },
40	NEW => { BYTES => 105, CHARS => 84, CHUNKS => 63, WORDS => 7, TABS => 0 },
41    },
42    { # DATALINE #6
43	OLD => { BYTES =>  55, CHARS => 53, CHUNKS => 51, WORDS => 8, TABS => 3 },
44	NEW => { BYTES =>  76, CHARS => 74, CHUNKS => 72, WORDS => 8, TABS => 0 },
45    },
46    { # DATALINE #7
47	OLD => { BYTES =>  42, CHARS => 40, CHUNKS => 38, WORDS => 7, TABS => 4 },
48	NEW => { BYTES =>  65, CHARS => 63, CHUNKS => 61, WORDS => 7, TABS => 0 },
49    },
50    { # DATALINE #8
51	OLD => { BYTES =>  80, CHARS => 65, CHUNKS => 52, WORDS => 9, TABS => 1 },
52	NEW => { BYTES =>  87, CHARS => 72, CHUNKS => 59, WORDS => 9, TABS => 0 },
53    },
54    { # DATALINE #9
55	OLD => { BYTES =>  43, CHARS => 41, CHUNKS => 41, WORDS => 7, TABS => 3 },
56	NEW => { BYTES =>  63, CHARS => 61, CHUNKS => 61, WORDS => 7, TABS => 0 },
57    },
58);
59
60$| = 1;
61my $numtests = @DATA;
62print "1..$numtests\n";
63
64$Errors += table_ok();
65check_data();
66
67if ($Errors) {
68    die "Error count: $Errors";
69} else {
70    exit(0);
71}
72
73
74# first some sanity checks
75sub table_ok {
76    my $bad = 0;
77    for my $i ( 1 .. $#DATA ) {
78
79	if ( $DATA[$i]{NEW}{TABS} ) {
80	    warn "new data should have no tabs in it at table line $i";
81	    $bad++;
82	}
83
84	if ( $DATA[$i]{NEW}{WORDS} != $DATA[$i]{OLD}{WORDS} ) {
85	    warn "word count shouldn't change upon tab expansion at table line $i";
86	    $bad++;
87	}
88    }
89    print $bad ? "not " : "", "ok 1\n";
90    return $bad;
91}
92
93sub check($$$$) {
94    die "expected 4 arguments" unless @_ == 4;
95    my ($found, $index, $version, $item) = @_;
96    my $expected = $DATA[$index]{$version}{$item};
97    return 1 if $found == $expected;
98    warn sprintf("%s line %d expected %d %s, found %d instead",
99		  ucfirst(lc($version)),
100			  $index,     $expected,
101					 lc($item),
102						 $found);
103    return 0;
104}
105
106sub check_data {
107
108    binmode(DATA, ":utf8") || die "can't binmode DATA to utf8: $!";
109    local($_);
110    while ( <DATA> ) {
111
112	my $bad = 0;
113
114	if ($. > $#DATA) {
115	    die "too many lines of data";
116	}
117
118	$DATA[$.]{OLD}{DATA} = $_;
119
120	my($char_count,  $byte_count, $chunk_count, $word_count, $tab_count);
121
122	$byte_count  = bytes::length($_);
123	$char_count  = length();
124	$chunk_count = () = /\X/g;
125	$word_count  = () = /(?:(?=\pL)\X)+/g;
126	$tab_count   = y/\t//;
127
128	$bad++ unless check($byte_count,  $., "OLD", "BYTES");
129	$bad++ unless check($char_count,  $., "OLD", "CHARS");
130	$bad++ unless check($chunk_count, $., "OLD", "CHUNKS");
131	$bad++ unless check($word_count,  $., "OLD", "WORDS");
132	$bad++ unless check($tab_count,   $., "OLD", "TABS");
133
134	$_ = expand($_);
135
136	$DATA[$.]{NEW}{DATA} = $_;
137
138	$byte_count  = bytes::length($_);
139	$char_count  = length();
140	$chunk_count = () = /\X/g;
141	$word_count  = () = /(?:(?=\pL)\X)+/g;
142	$tab_count   = y/\t//;
143
144	$bad++ unless check($byte_count,  $., "NEW", "BYTES");
145	$bad++ unless check($char_count,  $., "NEW", "CHARS");
146	$bad++ unless check($chunk_count, $., "NEW", "CHUNKS");
147	$bad++ unless check($word_count,  $., "NEW", "WORDS");
148	$bad++ unless check($tab_count,   $., "NEW", "TABS");
149
150	$_ = unexpand($_);
151
152	if ($_ ne $DATA[$.]{OLD}{DATA}) {
153	    warn "expand/unexpand round-trip equivalency failed at line $.";
154	    warn sprintf("  Expected:\n%s\n%v02x\n  But got:\n%s\n%v02x\n",
155		    ( $DATA[$.]{OLD}{DATA} ) x 2, ($_) x 2 );
156	    $bad++;
157	}
158
159	my $num = $. + 1;
160	print $bad ? "not " : "", "ok $num\n";
161	$Errors += $bad;
162
163    }
164
165}
166
167
168__DATA__
169	De los sos o̲j̲o̲s̲ 		tan fuertemientre l̲l̲o̲r̲a̲n̲d̲o̲,
170	tornava la cabeça		i estávalos catando.
171	Vio puertas abiertas		e uços sin cañados,
172	alcándaras vázias		sin pielles e sin mantos
173	e s̲i̲n̲ f̲a̲l̲c̲o̲n̲e̲s̲			e s̲i̲n̲ a̲d̲t̲o̲r̲e̲s̲ mudados.
174	Sospiró mio Çid,		ca mucho avie grandes cuidados.
175	Fabló mio Çid			bien e tan mesurado:
176grado a tí, s̳e̳ñ̳o̳r̳ p̳a̳d̳r̳e̳,	que estás en alto!
177	Esto me an buelto		mis enemigos malos.”
178