xref: /freebsd/contrib/kyua/utils/cmdline/ui_test.cpp (revision b0d29bc47dba79f6f38e67eabadfb4b32ffd9390)
1*b0d29bc4SBrooks Davis // Copyright 2011 The Kyua Authors.
2*b0d29bc4SBrooks Davis // All rights reserved.
3*b0d29bc4SBrooks Davis //
4*b0d29bc4SBrooks Davis // Redistribution and use in source and binary forms, with or without
5*b0d29bc4SBrooks Davis // modification, are permitted provided that the following conditions are
6*b0d29bc4SBrooks Davis // met:
7*b0d29bc4SBrooks Davis //
8*b0d29bc4SBrooks Davis // * Redistributions of source code must retain the above copyright
9*b0d29bc4SBrooks Davis //   notice, this list of conditions and the following disclaimer.
10*b0d29bc4SBrooks Davis // * Redistributions in binary form must reproduce the above copyright
11*b0d29bc4SBrooks Davis //   notice, this list of conditions and the following disclaimer in the
12*b0d29bc4SBrooks Davis //   documentation and/or other materials provided with the distribution.
13*b0d29bc4SBrooks Davis // * Neither the name of Google Inc. nor the names of its contributors
14*b0d29bc4SBrooks Davis //   may be used to endorse or promote products derived from this software
15*b0d29bc4SBrooks Davis //   without specific prior written permission.
16*b0d29bc4SBrooks Davis //
17*b0d29bc4SBrooks Davis // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18*b0d29bc4SBrooks Davis // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19*b0d29bc4SBrooks Davis // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20*b0d29bc4SBrooks Davis // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21*b0d29bc4SBrooks Davis // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22*b0d29bc4SBrooks Davis // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23*b0d29bc4SBrooks Davis // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24*b0d29bc4SBrooks Davis // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25*b0d29bc4SBrooks Davis // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26*b0d29bc4SBrooks Davis // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27*b0d29bc4SBrooks Davis // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*b0d29bc4SBrooks Davis 
29*b0d29bc4SBrooks Davis #include "utils/cmdline/ui.hpp"
30*b0d29bc4SBrooks Davis 
31*b0d29bc4SBrooks Davis #if defined(HAVE_CONFIG_H)
32*b0d29bc4SBrooks Davis #   include "config.h"
33*b0d29bc4SBrooks Davis #endif
34*b0d29bc4SBrooks Davis 
35*b0d29bc4SBrooks Davis extern "C" {
36*b0d29bc4SBrooks Davis #include <sys/param.h>
37*b0d29bc4SBrooks Davis #include <sys/ioctl.h>
38*b0d29bc4SBrooks Davis 
39*b0d29bc4SBrooks Davis #include <fcntl.h>
40*b0d29bc4SBrooks Davis #if defined(HAVE_TERMIOS_H)
41*b0d29bc4SBrooks Davis #   include <termios.h>
42*b0d29bc4SBrooks Davis #endif
43*b0d29bc4SBrooks Davis #include <unistd.h>
44*b0d29bc4SBrooks Davis }
45*b0d29bc4SBrooks Davis 
46*b0d29bc4SBrooks Davis #include <cerrno>
47*b0d29bc4SBrooks Davis #include <cstring>
48*b0d29bc4SBrooks Davis 
49*b0d29bc4SBrooks Davis #include <atf-c++.hpp>
50*b0d29bc4SBrooks Davis 
51*b0d29bc4SBrooks Davis #include "utils/cmdline/globals.hpp"
52*b0d29bc4SBrooks Davis #include "utils/cmdline/ui_mock.hpp"
53*b0d29bc4SBrooks Davis #include "utils/env.hpp"
54*b0d29bc4SBrooks Davis #include "utils/format/macros.hpp"
55*b0d29bc4SBrooks Davis #include "utils/optional.ipp"
56*b0d29bc4SBrooks Davis #include "utils/text/table.hpp"
57*b0d29bc4SBrooks Davis 
58*b0d29bc4SBrooks Davis namespace cmdline = utils::cmdline;
59*b0d29bc4SBrooks Davis namespace text = utils::text;
60*b0d29bc4SBrooks Davis 
61*b0d29bc4SBrooks Davis using utils::none;
62*b0d29bc4SBrooks Davis using utils::optional;
63*b0d29bc4SBrooks Davis 
64*b0d29bc4SBrooks Davis 
65*b0d29bc4SBrooks Davis namespace {
66*b0d29bc4SBrooks Davis 
67*b0d29bc4SBrooks Davis 
68*b0d29bc4SBrooks Davis /// Reopens stdout as a tty and returns its width.
69*b0d29bc4SBrooks Davis ///
70*b0d29bc4SBrooks Davis /// \return The width of the tty in columns.  If the width is wider than 80, the
71*b0d29bc4SBrooks Davis /// result is 5 columns narrower to match the screen_width() algorithm.
72*b0d29bc4SBrooks Davis static std::size_t
reopen_stdout(void)73*b0d29bc4SBrooks Davis reopen_stdout(void)
74*b0d29bc4SBrooks Davis {
75*b0d29bc4SBrooks Davis     const int fd = ::open("/dev/tty", O_WRONLY);
76*b0d29bc4SBrooks Davis     if (fd == -1)
77*b0d29bc4SBrooks Davis         ATF_SKIP(F("Cannot open tty for test: %s") % ::strerror(errno));
78*b0d29bc4SBrooks Davis     struct ::winsize ws;
79*b0d29bc4SBrooks Davis     if (::ioctl(fd, TIOCGWINSZ, &ws) == -1)
80*b0d29bc4SBrooks Davis         ATF_SKIP(F("Cannot determine size of tty: %s") % ::strerror(errno));
81*b0d29bc4SBrooks Davis 
82*b0d29bc4SBrooks Davis     if (fd != STDOUT_FILENO) {
83*b0d29bc4SBrooks Davis         if (::dup2(fd, STDOUT_FILENO) == -1)
84*b0d29bc4SBrooks Davis             ATF_SKIP(F("Failed to redirect stdout: %s") % ::strerror(errno));
85*b0d29bc4SBrooks Davis         ::close(fd);
86*b0d29bc4SBrooks Davis     }
87*b0d29bc4SBrooks Davis 
88*b0d29bc4SBrooks Davis     return ws.ws_col >= 80 ? ws.ws_col - 5 : ws.ws_col;
89*b0d29bc4SBrooks Davis }
90*b0d29bc4SBrooks Davis 
91*b0d29bc4SBrooks Davis 
92*b0d29bc4SBrooks Davis }  // anonymous namespace
93*b0d29bc4SBrooks Davis 
94*b0d29bc4SBrooks Davis 
95*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(ui__screen_width__columns_set__no_tty);
ATF_TEST_CASE_BODY(ui__screen_width__columns_set__no_tty)96*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(ui__screen_width__columns_set__no_tty)
97*b0d29bc4SBrooks Davis {
98*b0d29bc4SBrooks Davis     utils::setenv("COLUMNS", "4321");
99*b0d29bc4SBrooks Davis     ::close(STDOUT_FILENO);
100*b0d29bc4SBrooks Davis 
101*b0d29bc4SBrooks Davis     cmdline::ui ui;
102*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(4321 - 5, ui.screen_width().get());
103*b0d29bc4SBrooks Davis }
104*b0d29bc4SBrooks Davis 
105*b0d29bc4SBrooks Davis 
106*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(ui__screen_width__columns_set__tty);
ATF_TEST_CASE_BODY(ui__screen_width__columns_set__tty)107*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(ui__screen_width__columns_set__tty)
108*b0d29bc4SBrooks Davis {
109*b0d29bc4SBrooks Davis     utils::setenv("COLUMNS", "4321");
110*b0d29bc4SBrooks Davis     (void)reopen_stdout();
111*b0d29bc4SBrooks Davis 
112*b0d29bc4SBrooks Davis     cmdline::ui ui;
113*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(4321 - 5, ui.screen_width().get());
114*b0d29bc4SBrooks Davis }
115*b0d29bc4SBrooks Davis 
116*b0d29bc4SBrooks Davis 
117*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(ui__screen_width__columns_empty__no_tty);
ATF_TEST_CASE_BODY(ui__screen_width__columns_empty__no_tty)118*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(ui__screen_width__columns_empty__no_tty)
119*b0d29bc4SBrooks Davis {
120*b0d29bc4SBrooks Davis     utils::setenv("COLUMNS", "");
121*b0d29bc4SBrooks Davis     ::close(STDOUT_FILENO);
122*b0d29bc4SBrooks Davis 
123*b0d29bc4SBrooks Davis     cmdline::ui ui;
124*b0d29bc4SBrooks Davis     ATF_REQUIRE(!ui.screen_width());
125*b0d29bc4SBrooks Davis }
126*b0d29bc4SBrooks Davis 
127*b0d29bc4SBrooks Davis 
128*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(ui__screen_width__columns_empty__tty);
ATF_TEST_CASE_BODY(ui__screen_width__columns_empty__tty)129*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(ui__screen_width__columns_empty__tty)
130*b0d29bc4SBrooks Davis {
131*b0d29bc4SBrooks Davis     utils::setenv("COLUMNS", "");
132*b0d29bc4SBrooks Davis     const std::size_t columns = reopen_stdout();
133*b0d29bc4SBrooks Davis 
134*b0d29bc4SBrooks Davis     cmdline::ui ui;
135*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(columns, ui.screen_width().get());
136*b0d29bc4SBrooks Davis }
137*b0d29bc4SBrooks Davis 
138*b0d29bc4SBrooks Davis 
139*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(ui__screen_width__columns_invalid__no_tty);
ATF_TEST_CASE_BODY(ui__screen_width__columns_invalid__no_tty)140*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(ui__screen_width__columns_invalid__no_tty)
141*b0d29bc4SBrooks Davis {
142*b0d29bc4SBrooks Davis     utils::setenv("COLUMNS", "foo bar");
143*b0d29bc4SBrooks Davis     ::close(STDOUT_FILENO);
144*b0d29bc4SBrooks Davis 
145*b0d29bc4SBrooks Davis     cmdline::ui ui;
146*b0d29bc4SBrooks Davis     ATF_REQUIRE(!ui.screen_width());
147*b0d29bc4SBrooks Davis }
148*b0d29bc4SBrooks Davis 
149*b0d29bc4SBrooks Davis 
150*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(ui__screen_width__columns_invalid__tty);
ATF_TEST_CASE_BODY(ui__screen_width__columns_invalid__tty)151*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(ui__screen_width__columns_invalid__tty)
152*b0d29bc4SBrooks Davis {
153*b0d29bc4SBrooks Davis     utils::setenv("COLUMNS", "foo bar");
154*b0d29bc4SBrooks Davis     const std::size_t columns = reopen_stdout();
155*b0d29bc4SBrooks Davis 
156*b0d29bc4SBrooks Davis     cmdline::ui ui;
157*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(columns, ui.screen_width().get());
158*b0d29bc4SBrooks Davis }
159*b0d29bc4SBrooks Davis 
160*b0d29bc4SBrooks Davis 
161*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(ui__screen_width__tty_is_file);
ATF_TEST_CASE_BODY(ui__screen_width__tty_is_file)162*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(ui__screen_width__tty_is_file)
163*b0d29bc4SBrooks Davis {
164*b0d29bc4SBrooks Davis     utils::unsetenv("COLUMNS");
165*b0d29bc4SBrooks Davis     const int fd = ::open("test.txt", O_WRONLY | O_CREAT | O_TRUNC, 0755);
166*b0d29bc4SBrooks Davis     ATF_REQUIRE(fd != -1);
167*b0d29bc4SBrooks Davis     if (fd != STDOUT_FILENO) {
168*b0d29bc4SBrooks Davis         ATF_REQUIRE(::dup2(fd, STDOUT_FILENO) != -1);
169*b0d29bc4SBrooks Davis         ::close(fd);
170*b0d29bc4SBrooks Davis     }
171*b0d29bc4SBrooks Davis 
172*b0d29bc4SBrooks Davis     cmdline::ui ui;
173*b0d29bc4SBrooks Davis     ATF_REQUIRE(!ui.screen_width());
174*b0d29bc4SBrooks Davis }
175*b0d29bc4SBrooks Davis 
176*b0d29bc4SBrooks Davis 
177*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(ui__screen_width__cached);
ATF_TEST_CASE_BODY(ui__screen_width__cached)178*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(ui__screen_width__cached)
179*b0d29bc4SBrooks Davis {
180*b0d29bc4SBrooks Davis     cmdline::ui ui;
181*b0d29bc4SBrooks Davis 
182*b0d29bc4SBrooks Davis     utils::setenv("COLUMNS", "100");
183*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(100 - 5, ui.screen_width().get());
184*b0d29bc4SBrooks Davis 
185*b0d29bc4SBrooks Davis     utils::setenv("COLUMNS", "80");
186*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(100 - 5, ui.screen_width().get());
187*b0d29bc4SBrooks Davis 
188*b0d29bc4SBrooks Davis     utils::unsetenv("COLUMNS");
189*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(100 - 5, ui.screen_width().get());
190*b0d29bc4SBrooks Davis }
191*b0d29bc4SBrooks Davis 
192*b0d29bc4SBrooks Davis 
193*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(ui__err);
ATF_TEST_CASE_BODY(ui__err)194*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(ui__err)
195*b0d29bc4SBrooks Davis {
196*b0d29bc4SBrooks Davis     cmdline::ui_mock ui(10);  // Keep shorter than message.
197*b0d29bc4SBrooks Davis     ui.err("This is a short message");
198*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(1, ui.err_log().size());
199*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ("This is a short message", ui.err_log()[0]);
200*b0d29bc4SBrooks Davis     ATF_REQUIRE(ui.out_log().empty());
201*b0d29bc4SBrooks Davis }
202*b0d29bc4SBrooks Davis 
203*b0d29bc4SBrooks Davis 
204*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(ui__err__tolerates_newline);
ATF_TEST_CASE_BODY(ui__err__tolerates_newline)205*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(ui__err__tolerates_newline)
206*b0d29bc4SBrooks Davis {
207*b0d29bc4SBrooks Davis     cmdline::ui_mock ui(10);  // Keep shorter than message.
208*b0d29bc4SBrooks Davis     ui.err("This is a short message\n");
209*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(1, ui.err_log().size());
210*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ("This is a short message\n", ui.err_log()[0]);
211*b0d29bc4SBrooks Davis     ATF_REQUIRE(ui.out_log().empty());
212*b0d29bc4SBrooks Davis }
213*b0d29bc4SBrooks Davis 
214*b0d29bc4SBrooks Davis 
215*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(ui__out);
ATF_TEST_CASE_BODY(ui__out)216*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(ui__out)
217*b0d29bc4SBrooks Davis {
218*b0d29bc4SBrooks Davis     cmdline::ui_mock ui(10);  // Keep shorter than message.
219*b0d29bc4SBrooks Davis     ui.out("This is a short message");
220*b0d29bc4SBrooks Davis     ATF_REQUIRE(ui.err_log().empty());
221*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(1, ui.out_log().size());
222*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ("This is a short message", ui.out_log()[0]);
223*b0d29bc4SBrooks Davis }
224*b0d29bc4SBrooks Davis 
225*b0d29bc4SBrooks Davis 
226*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(ui__out__tolerates_newline);
ATF_TEST_CASE_BODY(ui__out__tolerates_newline)227*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(ui__out__tolerates_newline)
228*b0d29bc4SBrooks Davis {
229*b0d29bc4SBrooks Davis     cmdline::ui_mock ui(10);  // Keep shorter than message.
230*b0d29bc4SBrooks Davis     ui.out("This is a short message\n");
231*b0d29bc4SBrooks Davis     ATF_REQUIRE(ui.err_log().empty());
232*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(1, ui.out_log().size());
233*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ("This is a short message\n", ui.out_log()[0]);
234*b0d29bc4SBrooks Davis }
235*b0d29bc4SBrooks Davis 
236*b0d29bc4SBrooks Davis 
237*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(ui__out_wrap__no_refill);
ATF_TEST_CASE_BODY(ui__out_wrap__no_refill)238*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(ui__out_wrap__no_refill)
239*b0d29bc4SBrooks Davis {
240*b0d29bc4SBrooks Davis     cmdline::ui_mock ui(100);
241*b0d29bc4SBrooks Davis     ui.out_wrap("This is a short message");
242*b0d29bc4SBrooks Davis     ATF_REQUIRE(ui.err_log().empty());
243*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(1, ui.out_log().size());
244*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ("This is a short message", ui.out_log()[0]);
245*b0d29bc4SBrooks Davis }
246*b0d29bc4SBrooks Davis 
247*b0d29bc4SBrooks Davis 
248*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(ui__out_wrap__refill);
ATF_TEST_CASE_BODY(ui__out_wrap__refill)249*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(ui__out_wrap__refill)
250*b0d29bc4SBrooks Davis {
251*b0d29bc4SBrooks Davis     cmdline::ui_mock ui(16);
252*b0d29bc4SBrooks Davis     ui.out_wrap("This is a short message");
253*b0d29bc4SBrooks Davis     ATF_REQUIRE(ui.err_log().empty());
254*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(2, ui.out_log().size());
255*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ("This is a short", ui.out_log()[0]);
256*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ("message", ui.out_log()[1]);
257*b0d29bc4SBrooks Davis }
258*b0d29bc4SBrooks Davis 
259*b0d29bc4SBrooks Davis 
260*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(ui__out_tag_wrap__no_refill);
ATF_TEST_CASE_BODY(ui__out_tag_wrap__no_refill)261*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(ui__out_tag_wrap__no_refill)
262*b0d29bc4SBrooks Davis {
263*b0d29bc4SBrooks Davis     cmdline::ui_mock ui(100);
264*b0d29bc4SBrooks Davis     ui.out_tag_wrap("Some long tag: ", "This is a short message");
265*b0d29bc4SBrooks Davis     ATF_REQUIRE(ui.err_log().empty());
266*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(1, ui.out_log().size());
267*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ("Some long tag: This is a short message", ui.out_log()[0]);
268*b0d29bc4SBrooks Davis }
269*b0d29bc4SBrooks Davis 
270*b0d29bc4SBrooks Davis 
271*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(ui__out_tag_wrap__refill__repeat);
ATF_TEST_CASE_BODY(ui__out_tag_wrap__refill__repeat)272*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(ui__out_tag_wrap__refill__repeat)
273*b0d29bc4SBrooks Davis {
274*b0d29bc4SBrooks Davis     cmdline::ui_mock ui(32);
275*b0d29bc4SBrooks Davis     ui.out_tag_wrap("Some long tag: ", "This is a short message");
276*b0d29bc4SBrooks Davis     ATF_REQUIRE(ui.err_log().empty());
277*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(2, ui.out_log().size());
278*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ("Some long tag: This is a short", ui.out_log()[0]);
279*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ("Some long tag: message", ui.out_log()[1]);
280*b0d29bc4SBrooks Davis }
281*b0d29bc4SBrooks Davis 
282*b0d29bc4SBrooks Davis 
283*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(ui__out_tag_wrap__refill__no_repeat);
ATF_TEST_CASE_BODY(ui__out_tag_wrap__refill__no_repeat)284*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(ui__out_tag_wrap__refill__no_repeat)
285*b0d29bc4SBrooks Davis {
286*b0d29bc4SBrooks Davis     cmdline::ui_mock ui(32);
287*b0d29bc4SBrooks Davis     ui.out_tag_wrap("Some long tag: ", "This is a short message", false);
288*b0d29bc4SBrooks Davis     ATF_REQUIRE(ui.err_log().empty());
289*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(2, ui.out_log().size());
290*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ("Some long tag: This is a short", ui.out_log()[0]);
291*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ("               message", ui.out_log()[1]);
292*b0d29bc4SBrooks Davis }
293*b0d29bc4SBrooks Davis 
294*b0d29bc4SBrooks Davis 
295*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(ui__out_tag_wrap__tag_too_long);
ATF_TEST_CASE_BODY(ui__out_tag_wrap__tag_too_long)296*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(ui__out_tag_wrap__tag_too_long)
297*b0d29bc4SBrooks Davis {
298*b0d29bc4SBrooks Davis     cmdline::ui_mock ui(5);
299*b0d29bc4SBrooks Davis     ui.out_tag_wrap("Some long tag: ", "This is a short message");
300*b0d29bc4SBrooks Davis     ATF_REQUIRE(ui.err_log().empty());
301*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(1, ui.out_log().size());
302*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ("Some long tag: This is a short message", ui.out_log()[0]);
303*b0d29bc4SBrooks Davis }
304*b0d29bc4SBrooks Davis 
305*b0d29bc4SBrooks Davis 
306*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(ui__out_table__empty);
ATF_TEST_CASE_BODY(ui__out_table__empty)307*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(ui__out_table__empty)
308*b0d29bc4SBrooks Davis {
309*b0d29bc4SBrooks Davis     const text::table table(3);
310*b0d29bc4SBrooks Davis 
311*b0d29bc4SBrooks Davis     text::table_formatter formatter;
312*b0d29bc4SBrooks Davis     formatter.set_separator(" | ");
313*b0d29bc4SBrooks Davis     formatter.set_column_width(0, 23);
314*b0d29bc4SBrooks Davis     formatter.set_column_width(1, text::table_formatter::width_refill);
315*b0d29bc4SBrooks Davis 
316*b0d29bc4SBrooks Davis     cmdline::ui_mock ui(52);
317*b0d29bc4SBrooks Davis     ui.out_table(table, formatter, "    ");
318*b0d29bc4SBrooks Davis     ATF_REQUIRE(ui.out_log().empty());
319*b0d29bc4SBrooks Davis }
320*b0d29bc4SBrooks Davis 
321*b0d29bc4SBrooks Davis 
322*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(ui__out_table__not_empty);
ATF_TEST_CASE_BODY(ui__out_table__not_empty)323*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(ui__out_table__not_empty)
324*b0d29bc4SBrooks Davis {
325*b0d29bc4SBrooks Davis     text::table table(3);
326*b0d29bc4SBrooks Davis     {
327*b0d29bc4SBrooks Davis         text::table_row row;
328*b0d29bc4SBrooks Davis         row.push_back("First");
329*b0d29bc4SBrooks Davis         row.push_back("Second");
330*b0d29bc4SBrooks Davis         row.push_back("Third");
331*b0d29bc4SBrooks Davis         table.add_row(row);
332*b0d29bc4SBrooks Davis     }
333*b0d29bc4SBrooks Davis     {
334*b0d29bc4SBrooks Davis         text::table_row row;
335*b0d29bc4SBrooks Davis         row.push_back("Fourth with some text");
336*b0d29bc4SBrooks Davis         row.push_back("Fifth with some more text");
337*b0d29bc4SBrooks Davis         row.push_back("Sixth foo");
338*b0d29bc4SBrooks Davis         table.add_row(row);
339*b0d29bc4SBrooks Davis     }
340*b0d29bc4SBrooks Davis 
341*b0d29bc4SBrooks Davis     text::table_formatter formatter;
342*b0d29bc4SBrooks Davis     formatter.set_separator(" | ");
343*b0d29bc4SBrooks Davis     formatter.set_column_width(0, 23);
344*b0d29bc4SBrooks Davis     formatter.set_column_width(1, text::table_formatter::width_refill);
345*b0d29bc4SBrooks Davis 
346*b0d29bc4SBrooks Davis     cmdline::ui_mock ui(52);
347*b0d29bc4SBrooks Davis     ui.out_table(table, formatter, "    ");
348*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(4, ui.out_log().size());
349*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ("    First                   | Second     | Third",
350*b0d29bc4SBrooks Davis                    ui.out_log()[0]);
351*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ("    Fourth with some text   | Fifth with | Sixth foo",
352*b0d29bc4SBrooks Davis                    ui.out_log()[1]);
353*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ("                            | some more  | ",
354*b0d29bc4SBrooks Davis                    ui.out_log()[2]);
355*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ("                            | text       | ",
356*b0d29bc4SBrooks Davis                    ui.out_log()[3]);
357*b0d29bc4SBrooks Davis }
358*b0d29bc4SBrooks Davis 
359*b0d29bc4SBrooks Davis 
360*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(print_error);
ATF_TEST_CASE_BODY(print_error)361*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(print_error)
362*b0d29bc4SBrooks Davis {
363*b0d29bc4SBrooks Davis     cmdline::init("error-program");
364*b0d29bc4SBrooks Davis     cmdline::ui_mock ui;
365*b0d29bc4SBrooks Davis     cmdline::print_error(&ui, "The error.");
366*b0d29bc4SBrooks Davis     ATF_REQUIRE(ui.out_log().empty());
367*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(1, ui.err_log().size());
368*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ("error-program: E: The error.", ui.err_log()[0]);
369*b0d29bc4SBrooks Davis }
370*b0d29bc4SBrooks Davis 
371*b0d29bc4SBrooks Davis 
372*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(print_info);
ATF_TEST_CASE_BODY(print_info)373*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(print_info)
374*b0d29bc4SBrooks Davis {
375*b0d29bc4SBrooks Davis     cmdline::init("info-program");
376*b0d29bc4SBrooks Davis     cmdline::ui_mock ui;
377*b0d29bc4SBrooks Davis     cmdline::print_info(&ui, "The info.");
378*b0d29bc4SBrooks Davis     ATF_REQUIRE(ui.out_log().empty());
379*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(1, ui.err_log().size());
380*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ("info-program: I: The info.", ui.err_log()[0]);
381*b0d29bc4SBrooks Davis }
382*b0d29bc4SBrooks Davis 
383*b0d29bc4SBrooks Davis 
384*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(print_warning);
ATF_TEST_CASE_BODY(print_warning)385*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(print_warning)
386*b0d29bc4SBrooks Davis {
387*b0d29bc4SBrooks Davis     cmdline::init("warning-program");
388*b0d29bc4SBrooks Davis     cmdline::ui_mock ui;
389*b0d29bc4SBrooks Davis     cmdline::print_warning(&ui, "The warning.");
390*b0d29bc4SBrooks Davis     ATF_REQUIRE(ui.out_log().empty());
391*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(1, ui.err_log().size());
392*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ("warning-program: W: The warning.", ui.err_log()[0]);
393*b0d29bc4SBrooks Davis }
394*b0d29bc4SBrooks Davis 
395*b0d29bc4SBrooks Davis 
ATF_INIT_TEST_CASES(tcs)396*b0d29bc4SBrooks Davis ATF_INIT_TEST_CASES(tcs)
397*b0d29bc4SBrooks Davis {
398*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, ui__screen_width__columns_set__no_tty);
399*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, ui__screen_width__columns_set__tty);
400*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, ui__screen_width__columns_empty__no_tty);
401*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, ui__screen_width__columns_empty__tty);
402*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, ui__screen_width__columns_invalid__no_tty);
403*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, ui__screen_width__columns_invalid__tty);
404*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, ui__screen_width__tty_is_file);
405*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, ui__screen_width__cached);
406*b0d29bc4SBrooks Davis 
407*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, ui__err);
408*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, ui__err__tolerates_newline);
409*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, ui__out);
410*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, ui__out__tolerates_newline);
411*b0d29bc4SBrooks Davis 
412*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, ui__out_wrap__no_refill);
413*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, ui__out_wrap__refill);
414*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, ui__out_tag_wrap__no_refill);
415*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, ui__out_tag_wrap__refill__repeat);
416*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, ui__out_tag_wrap__refill__no_repeat);
417*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, ui__out_tag_wrap__tag_too_long);
418*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, ui__out_table__empty);
419*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, ui__out_table__not_empty);
420*b0d29bc4SBrooks Davis 
421*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, print_error);
422*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, print_info);
423*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, print_warning);
424*b0d29bc4SBrooks Davis }
425