1 // Copyright 2010 Google Inc.
2 // All rights reserved.
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // * Neither the name of Google Inc. nor the names of its contributors
14 // may be used to endorse or promote products derived from this software
15 // without specific prior written permission.
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #include "utils/format/formatter.hpp"
33 #include <atf-c++.hpp>
35 #include "utils/format/exceptions.hpp"
36 #include "utils/format/macros.hpp"
38 namespace format
= utils::format
;
44 /// Wraps an integer in a C++ class.
46 /// This custom type exists to ensure that we can feed arbitrary objects that
47 /// support operator<< to the formatter;
49 /// The wrapped integer.
53 /// Constructs a new wrapper.
55 /// \param value_ The value to wrap.
56 int_wrapper(const int value_
) : _value(value_
)
60 /// Returns the wrapped value.
62 /// \return An integer.
71 /// Writes a wrapped integer into an output stream.
73 /// \param output The output stream into which to place the integer.
74 /// \param wrapper The wrapped integer.
76 /// \return The output stream.
78 operator<<(std::ostream
& output
, const int_wrapper
& wrapper
)
80 return (output
<< wrapper
.value());
84 } // anonymous namespace
87 /// Calls ATF_REQUIRE_EQ on an expected string and a formatter.
89 /// This is pure syntactic sugar to avoid calling the str() method on all the
90 /// individual tests below, which results in very long lines that require
91 /// wrapping and clutter readability.
93 /// \param expected The expected string generated by the formatter.
94 /// \param formatter The formatter to test.
95 #define EQ(expected, formatter) ATF_REQUIRE_EQ(expected, (formatter).str())
98 ATF_TEST_CASE_WITHOUT_HEAD(no_fields
);
99 ATF_TEST_CASE_BODY(no_fields
)
101 EQ("Plain string", F("Plain string"));
105 ATF_TEST_CASE_WITHOUT_HEAD(one_field
);
106 ATF_TEST_CASE_BODY(one_field
)
108 EQ("foo", F("%sfoo") % "");
109 EQ(" foo", F("%sfoo") % " ");
110 EQ("foo ", F("foo %s") % "");
111 EQ("foo bar", F("foo %s") % "bar");
112 EQ("foo bar baz", F("foo %s baz") % "bar");
113 EQ("foo %s %s", F("foo %s %s") % "%s" % "%s");
117 ATF_TEST_CASE_WITHOUT_HEAD(many_fields
);
118 ATF_TEST_CASE_BODY(many_fields
)
120 EQ("", F("%s%s") % "" % "");
121 EQ("foo", F("%s%s%s") % "" % "foo" % "");
122 EQ("some 5 text", F("%s %s %s") % "some" % 5 % "text");
123 EQ("f%s 5 text", F("%s %s %s") % "f%s" % 5 % "text");
127 ATF_TEST_CASE_WITHOUT_HEAD(escape
);
128 ATF_TEST_CASE_BODY(escape
)
131 EQ("% %", F("%% %%"));
132 EQ("%% %%", F("%%%% %%%%"));
134 EQ("foo %", F("foo %%"));
135 EQ("foo bar %", F("foo %s %%") % "bar");
136 EQ("foo % bar", F("foo %% %s") % "bar");
138 EQ("foo %%", F("foo %s") % "%%");
139 EQ("foo a%%b", F("foo a%sb") % "%%");
140 EQ("foo a%%b", F("foo %s") % "a%%b");
142 EQ("foo % bar %%", F("foo %% %s %%%%") % "bar");
146 ATF_TEST_CASE_WITHOUT_HEAD(extra_args_error
);
147 ATF_TEST_CASE_BODY(extra_args_error
)
149 using format::extra_args_error
;
151 ATF_REQUIRE_THROW(extra_args_error
, F("foo") % "bar");
152 ATF_REQUIRE_THROW(extra_args_error
, F("foo %%") % "bar");
153 ATF_REQUIRE_THROW(extra_args_error
, F("foo %s") % "bar" % "baz");
154 ATF_REQUIRE_THROW(extra_args_error
, F("foo %s") % "%s" % "bar");
155 ATF_REQUIRE_THROW(extra_args_error
, F("%s foo %s") % "bar" % "baz" % "foo");
158 F("foo %s %s") % "bar" % "baz" % "something extra";
159 fail("extra_args_error not raised");
160 } catch (const extra_args_error
& e
) {
161 ATF_REQUIRE_EQ("foo %s %s", e
.format());
162 ATF_REQUIRE_EQ("something extra", e
.arg());
167 ATF_TEST_CASE_WITHOUT_HEAD(format__class
);
168 ATF_TEST_CASE_BODY(format__class
)
170 EQ("foo bar", F("%s") % std::string("foo bar"));
171 EQ("3", F("%s") % int_wrapper(3));
175 ATF_TEST_CASE_WITHOUT_HEAD(format__pointer
);
176 ATF_TEST_CASE_BODY(format__pointer
)
178 EQ("0xcafebabe", F("%s") % reinterpret_cast< void* >(0xcafebabe));
179 EQ("foo bar", F("%s") % "foo bar");
183 ATF_TEST_CASE_WITHOUT_HEAD(format__bool
);
184 ATF_TEST_CASE_BODY(format__bool
)
186 EQ("true", F("%s") % true);
187 EQ("false", F("%s") % false);
191 ATF_TEST_CASE_WITHOUT_HEAD(format__char
);
192 ATF_TEST_CASE_BODY(format__char
)
194 EQ("Z", F("%s") % 'Z');
198 ATF_TEST_CASE_WITHOUT_HEAD(format__float
);
199 ATF_TEST_CASE_BODY(format__float
)
201 EQ("3", F("%s") % 3.0);
202 EQ("3.0", F("%.1s") % 3.0);
203 EQ("3.0", F("%0.1s") % 3.0);
204 EQ(" 15.600", F("%8.3s") % 15.6);
205 EQ("01.52", F("%05.2s") % 1.52);
209 ATF_TEST_CASE_WITHOUT_HEAD(format__int
);
210 ATF_TEST_CASE_BODY(format__int
)
212 EQ("3", F("%s") % 3);
213 EQ("3", F("%0s") % 3);
214 EQ(" -123", F("%5s") % -123);
215 EQ("00078", F("%05s") % 78);
219 ATF_TEST_CASE_WITHOUT_HEAD(format__error
);
220 ATF_TEST_CASE_BODY(format__error
)
222 using format::bad_format_error
;
224 ATF_REQUIRE_THROW_RE(bad_format_error
, "Trailing %", F("%"));
225 ATF_REQUIRE_THROW_RE(bad_format_error
, "Trailing %", F("f%"));
226 ATF_REQUIRE_THROW_RE(bad_format_error
, "Trailing %", F("f%%%"));
227 ATF_REQUIRE_THROW_RE(bad_format_error
, "Trailing %", F("ab %s cd%") % "cd");
229 ATF_REQUIRE_THROW_RE(bad_format_error
, "Invalid width", F("%1bs"));
231 ATF_REQUIRE_THROW_RE(bad_format_error
, "Invalid precision", F("%.s"));
232 ATF_REQUIRE_THROW_RE(bad_format_error
, "Invalid precision", F("%0.s"));
233 ATF_REQUIRE_THROW_RE(bad_format_error
, "Invalid precision", F("%123.s"));
234 ATF_REQUIRE_THROW_RE(bad_format_error
, "Invalid precision", F("%.12bs"));
236 ATF_REQUIRE_THROW_RE(bad_format_error
, "Unterminated", F("%c") % 'Z');
237 ATF_REQUIRE_THROW_RE(bad_format_error
, "Unterminated", F("%d") % 5);
238 ATF_REQUIRE_THROW_RE(bad_format_error
, "Unterminated", F("%.1f") % 3);
239 ATF_REQUIRE_THROW_RE(bad_format_error
, "Unterminated", F("%d%s") % 3 % "a");
242 F("foo %s%") % "bar";
243 fail("bad_format_error not raised");
244 } catch (const bad_format_error
& e
) {
245 ATF_REQUIRE_EQ("foo %s%", e
.format());
250 ATF_INIT_TEST_CASES(tcs
)
252 ATF_ADD_TEST_CASE(tcs
, no_fields
);
253 ATF_ADD_TEST_CASE(tcs
, one_field
);
254 ATF_ADD_TEST_CASE(tcs
, many_fields
);
255 ATF_ADD_TEST_CASE(tcs
, escape
);
256 ATF_ADD_TEST_CASE(tcs
, extra_args_error
);
258 ATF_ADD_TEST_CASE(tcs
, format__class
);
259 ATF_ADD_TEST_CASE(tcs
, format__pointer
);
260 ATF_ADD_TEST_CASE(tcs
, format__bool
);
261 ATF_ADD_TEST_CASE(tcs
, format__char
);
262 ATF_ADD_TEST_CASE(tcs
, format__float
);
263 ATF_ADD_TEST_CASE(tcs
, format__int
);
264 ATF_ADD_TEST_CASE(tcs
, format__error
);