xref: /freebsd/usr.bin/wc/tests/wc_test.sh (revision 942815c54820783d3d4f7f6faa71ab7919b5f0e5)
1#
2# Copyright (c) 2023 Klara, Inc.
3#
4# SPDX-License-Identifier: BSD-2-Clause
5#
6
7#
8# These tests need to run in a multibyte locale with non-localized
9# error messages.
10#
11export LC_CTYPE=C.UTF-8
12export LC_MESSAGES=C
13
14#
15# Sample text containing multibyte characters
16#
17tv="Der bode en underlig gråsprængt en
18på den yderste nøgne ø; –
19han gjorde visst intet menneske mén
20hverken på land eller sjø;
21dog stundom gnistred hans øjne stygt, –
22helst mod uroligt vejr, –
23og da mente folk, at han var forrykt,
24og da var der få, som uden frykt
25kom Terje Vigen nær.
26"
27tvl=10
28tvw=55
29tvc=300
30tvm=283
31tvcL=42
32tvmL=39
33
34#
35# Run a series of tests using the same input file.  The first argument
36# is the name of the file.  The next three are the expected line,
37# word, and byte counts.  The optional fifth is the expected character
38# count; if not provided, it is expected to be identical to the byte
39# count.
40#
41atf_check_wc() {
42	local file="$1"
43	local l="$2"
44	local w="$3"
45	local c="$4"
46	local m="${5-$4}"
47
48	atf_check -o match:"^ +${l} +${w} +${c}\$" wc <"${file}"
49	atf_check -o match:"^ +${l}\$" wc -l <"${file}"
50	atf_check -o match:"^ +${w}\$" wc -w <"${file}"
51	atf_check -o match:"^ +${c}\$" wc -c <"${file}"
52	atf_check -o match:"^ +${m}\$" wc -m <"${file}"
53	atf_check -o match:"^ +${l} +${w} +${c} ${file}\$" wc "$file"
54	atf_check -o match:"^ +${l} ${file}\$" wc -l "$file"
55	atf_check -o match:"^ +${w} ${file}\$" wc -w "$file"
56	atf_check -o match:"^ +${c} ${file}\$" wc -c "$file"
57	atf_check -o match:"^ +${m} ${file}\$" wc -m "$file"
58}
59
60atf_test_case basic
61basic_head()
62{
63	atf_set "descr" "Basic test case"
64}
65basic_body()
66{
67	printf "a b\n" >foo
68	atf_check_wc foo 1 2 4
69}
70
71atf_test_case blank
72blank_head()
73{
74	atf_set "descr" "Input containing only blank lines"
75}
76blank_body()
77{
78	printf "\n\n\n" >foo
79	atf_check_wc foo 3 0 3
80}
81
82atf_test_case empty
83empty_head()
84{
85	atf_set "descr" "Empty input"
86}
87empty_body()
88{
89	printf "" >foo
90	atf_check_wc foo 0 0 0
91}
92
93atf_test_case invalid
94invalid_head()
95{
96	atf_set "descr" "Invalid multibyte input"
97}
98invalid_body()
99{
100	printf "a\377b\n" >foo
101	atf_check \
102	    -e match:"Illegal byte sequence" \
103	    -o match:"^ +4 foo$" \
104	    wc -m foo
105}
106
107atf_test_case multiline
108multiline_head()
109{
110	atf_set "descr" "Multiline, multibyte input"
111}
112multiline_body()
113{
114	printf "%s\n" "$tv" >foo
115	atf_check_wc foo $tvl $tvw $tvc $tvm
116	# longest line in bytes
117	atf_check -o match:"^ +$tvc +$tvcL foo" wc -cL foo
118	atf_check -o match:"^ +$tvc +$tvcL" wc -cL <foo
119	# longest line in characters
120	atf_check -o match:"^ +$tvm +$tvmL foo" wc -mL foo
121	atf_check -o match:"^ +$tvm +$tvmL" wc -mL <foo
122}
123
124atf_test_case multiline_repeated
125multiline_repeated_head()
126{
127	atf_set "descr" "Multiline input exceeding the input buffer size"
128}
129multiline_repeated_body()
130{
131	local c=0
132	while [ $c -lt 1000 ] ; do
133		printf "%1\$s\n%1\$s\n%1\$s\n%1\$s\n%1\$s\n" "$tv"
134		c=$((c+5))
135	done >foo
136	atf_check_wc foo $((tvl*c)) $((tvw*c)) $((tvc*c)) $((tvm*c))
137}
138
139atf_test_case total
140total_head()
141{
142	atf_set "descr" "Multiple inputs"
143}
144total_body()
145{
146	printf "%s\n" "$tv" >foo
147	printf "%s\n" "$tv" >bar
148	atf_check \
149	    -o match:"^ +$((tvl*2)) +$((tvw*2)) +$((tvc*2)) total$" \
150	    wc foo bar
151}
152
153atf_test_case unterminated
154unterminated_head()
155{
156	atf_set "descr" "Input not ending in newline"
157}
158unterminated_body()
159{
160	printf "a b" >foo
161	atf_check_wc foo 0 2 3
162}
163
164atf_test_case usage
165usage_head()
166{
167	atf_set "descr" "Trigger usage message"
168}
169usage_body()
170{
171	atf_check -s exit:1 -e match:"usage: wc" wc -\?
172}
173
174atf_test_case whitespace
175whitespace_head()
176{
177	atf_set "descr" "Input containing only whitespace and newlines"
178}
179whitespace_body()
180{
181	printf "\n \n\t\n" >foo
182	atf_check_wc foo 3 0 5
183}
184
185atf_init_test_cases()
186{
187	atf_add_test_case basic
188	atf_add_test_case blank
189	atf_add_test_case empty
190	atf_add_test_case invalid
191	atf_add_test_case multiline
192	atf_add_test_case multiline_repeated
193	atf_add_test_case total
194	atf_add_test_case unterminated
195	atf_add_test_case usage
196	atf_add_test_case whitespace
197}
198