/src/mozilla-central/xpcom/tests/gtest/TestTextFormatter.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
3 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
4 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
5 | | |
6 | | #include "nsTextFormatter.h" |
7 | | #include "nsString.h" |
8 | | #include "gtest/gtest.h" |
9 | | |
10 | | TEST(TextFormatter, Tests) |
11 | 0 | { |
12 | 0 | nsAutoString fmt(NS_LITERAL_STRING("%3$s %4$S %1$d %2$d %2$d %3$s")); |
13 | 0 | char utf8[] = "Hello"; |
14 | 0 | char16_t ucs2[]={'W', 'o', 'r', 'l', 'd', 0x4e00, 0xAc00, 0xFF45, 0x0103, 0x00}; |
15 | 0 | int d=3; |
16 | 0 |
|
17 | 0 | char16_t buf[256]; |
18 | 0 | nsTextFormatter::snprintf(buf, 256, fmt.get(), d, 333, utf8, ucs2); |
19 | 0 | nsAutoString out(buf); |
20 | 0 |
|
21 | 0 | const char16_t *uout = out.get(); |
22 | 0 | const char16_t expected[] = {0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, |
23 | 0 | 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x4E00, |
24 | 0 | 0xAC00, 0xFF45, 0x0103, 0x20, 0x33, |
25 | 0 | 0x20, 0x33, 0x33, 0x33, 0x20, 0x33, |
26 | 0 | 0x33, 0x33, 0x20, 0x48, 0x65, 0x6C, |
27 | 0 | 0x6C, 0x6F}; |
28 | 0 |
|
29 | 0 | for (uint32_t i=0; i<out.Length(); i++) { |
30 | 0 | ASSERT_EQ(uout[i], expected[i]); |
31 | 0 | } |
32 | 0 |
|
33 | 0 | // Test that an unrecognized escape is passed through. |
34 | 0 | nsString out2; |
35 | 0 | nsTextFormatter::ssprintf(out2, u"%1m!", 23); |
36 | 0 | EXPECT_STREQ("%1m!", NS_ConvertUTF16toUTF8(out2).get()); |
37 | 0 |
|
38 | 0 | // Treat NULL the same in both %s cases. |
39 | 0 | nsTextFormatter::ssprintf(out2, u"%s %S", (char*) nullptr, (char16_t*) nullptr); |
40 | 0 | EXPECT_STREQ("(null) (null)", NS_ConvertUTF16toUTF8(out2).get()); |
41 | 0 |
|
42 | 0 | nsTextFormatter::ssprintf(out2, u"%lld", INT64_MIN); |
43 | 0 | EXPECT_STREQ("-9223372036854775808", NS_ConvertUTF16toUTF8(out2).get()); |
44 | 0 |
|
45 | 0 | // Regression test for bug 1401821. |
46 | 0 | nsTextFormatter::ssprintf(out2, u"%*.f", 0, 23.2); |
47 | 0 | EXPECT_STREQ("23", NS_ConvertUTF16toUTF8(out2).get()); |
48 | 0 | } |
49 | | |
50 | | /* |
51 | | * Check misordered parameters |
52 | | */ |
53 | | |
54 | | TEST(TextFormatterOrdering, orders) |
55 | 0 | { |
56 | 0 | nsString out; |
57 | 0 |
|
58 | 0 | // plain list |
59 | 0 | nsTextFormatter::ssprintf(out, u"%S %S %S", u"1", u"2", u"3"); |
60 | 0 | EXPECT_STREQ("1 2 3", NS_ConvertUTF16toUTF8(out).get()); |
61 | 0 |
|
62 | 0 | // ordered list |
63 | 0 | nsTextFormatter::ssprintf(out, u"%2$S %3$S %1$S", u"1", u"2", u"3"); |
64 | 0 | EXPECT_STREQ("2 3 1", NS_ConvertUTF16toUTF8(out).get()); |
65 | 0 |
|
66 | 0 | // Mixed ordered list and non-ordered does not work. This shouldn't |
67 | 0 | // crash (hence the calls to ssprintf) but should fail for for |
68 | 0 | // snprintf. |
69 | 0 | nsTextFormatter::ssprintf(out, u"%2S %S %1$S", u"1", u"2", u"3"); |
70 | 0 | nsTextFormatter::ssprintf(out, u"%S %2$S", u"1", u"2"); |
71 | 0 | char16_t buffer[1024]; // plenty big |
72 | 0 | EXPECT_EQ(nsTextFormatter::snprintf(buffer, sizeof(buffer), u"%2S %S %1$S", u"1", u"2", u"3"), |
73 | 0 | uint32_t(-1)); |
74 | 0 | EXPECT_EQ(nsTextFormatter::snprintf(buffer, sizeof(buffer), u"%S %2$S", u"1", u"2"), |
75 | 0 | uint32_t(-1)); |
76 | 0 |
|
77 | 0 | // Referencing an extra param returns empty strings in release. |
78 | 0 | #ifndef DEBUG |
79 | 0 | nsTextFormatter::ssprintf(out, u" %2$S ", u"1"); |
80 | 0 | EXPECT_STREQ(" ", NS_ConvertUTF16toUTF8(out).get()); |
81 | 0 | #endif |
82 | 0 |
|
83 | 0 | // Double referencing existing argument works |
84 | 0 | nsTextFormatter::ssprintf(out, u"%1$S %1$S", u"1"); |
85 | 0 | EXPECT_STREQ("1 1", NS_ConvertUTF16toUTF8(out).get()); |
86 | 0 |
|
87 | 0 | // Dropping trailing argument works |
88 | 0 | nsTextFormatter::ssprintf(out, u" %1$S ", u"1", u"2"); |
89 | 0 | EXPECT_STREQ(" 1 ", NS_ConvertUTF16toUTF8(out).get()); |
90 | 0 |
|
91 | 0 | // Dropping leading arguments works |
92 | 0 | nsTextFormatter::ssprintf(out, u" %2$S ", u"1", u"2"); |
93 | 0 | EXPECT_STREQ(" 2 ", NS_ConvertUTF16toUTF8(out).get()); |
94 | 0 |
|
95 | 0 | // Dropping middle arguments works |
96 | 0 | nsTextFormatter::ssprintf(out, u" %3$S %1$S ", u"1", u"2", u"3"); |
97 | 0 | EXPECT_STREQ(" 3 1 ", NS_ConvertUTF16toUTF8(out).get()); |
98 | 0 | } |
99 | | |
100 | | /* |
101 | | * Tests to validate that horrible things don't happen if the passed-in |
102 | | * variable and the formatter don't match. |
103 | | */ |
104 | | TEST(TextFormatterTestMismatch, format_d) |
105 | 0 | { |
106 | 0 | nsString out; |
107 | 0 | // just for completeness, this is our format, and works |
108 | 0 | nsTextFormatter::ssprintf(out, u"%d", int(-1)); |
109 | 0 | EXPECT_STREQ("-1", NS_ConvertUTF16toUTF8(out).get()); |
110 | 0 | nsTextFormatter::ssprintf(out, u"%d", uint32_t(-1)); |
111 | 0 | EXPECT_STREQ("4294967295", NS_ConvertUTF16toUTF8(out).get()); |
112 | 0 | #ifndef DEBUG |
113 | 0 | nsTextFormatter::ssprintf(out, u"%d", float(3.5)); |
114 | 0 | EXPECT_STREQ("3.5", NS_ConvertUTF16toUTF8(out).get()); |
115 | 0 | nsTextFormatter::ssprintf(out, u"%d", "foo"); |
116 | 0 | EXPECT_STREQ("foo", NS_ConvertUTF16toUTF8(out).get()); |
117 | 0 | nsTextFormatter::ssprintf(out, u"%d", u"foo"); |
118 | 0 | EXPECT_STREQ("foo", NS_ConvertUTF16toUTF8(out).get()); |
119 | 0 | #endif |
120 | 0 | } |
121 | | |
122 | | TEST(TextFormatterTestMismatch, format_u) |
123 | 0 | { |
124 | 0 | nsString out; |
125 | 0 | nsTextFormatter::ssprintf(out, u"%u", int(-1)); |
126 | 0 | EXPECT_STREQ("4294967295", NS_ConvertUTF16toUTF8(out).get()); |
127 | 0 | // just for completeness, this is our format, and works |
128 | 0 | nsTextFormatter::ssprintf(out, u"%u", uint32_t(-1)); |
129 | 0 | EXPECT_STREQ("4294967295", NS_ConvertUTF16toUTF8(out).get()); |
130 | 0 | #ifndef DEBUG |
131 | 0 | nsTextFormatter::ssprintf(out, u"%u", float(3.5)); |
132 | 0 | EXPECT_STREQ("3.5", NS_ConvertUTF16toUTF8(out).get()); |
133 | 0 | nsTextFormatter::ssprintf(out, u"%u", "foo"); |
134 | 0 | EXPECT_STREQ("foo", NS_ConvertUTF16toUTF8(out).get()); |
135 | 0 | nsTextFormatter::ssprintf(out, u"%u", u"foo"); |
136 | 0 | EXPECT_STREQ("foo", NS_ConvertUTF16toUTF8(out).get()); |
137 | 0 | #endif |
138 | 0 | } |
139 | | |
140 | | TEST(TextFormatterTestMismatch, format_x) |
141 | 0 | { |
142 | 0 | nsString out; |
143 | 0 | nsTextFormatter::ssprintf(out, u"%x", int32_t(-1)); |
144 | 0 | EXPECT_STREQ("ffffffff", NS_ConvertUTF16toUTF8(out).get()); |
145 | 0 | // just for completeness, this is our format, and works |
146 | 0 | nsTextFormatter::ssprintf(out, u"%x", uint32_t(-1)); |
147 | 0 | EXPECT_STREQ("ffffffff", NS_ConvertUTF16toUTF8(out).get()); |
148 | 0 | #ifndef DEBUG |
149 | 0 | nsTextFormatter::ssprintf(out, u"%x", float(3.5)); |
150 | 0 | EXPECT_STREQ("3.5", NS_ConvertUTF16toUTF8(out).get()); |
151 | 0 | nsTextFormatter::ssprintf(out, u"%x", "foo"); |
152 | 0 | EXPECT_STREQ("foo", NS_ConvertUTF16toUTF8(out).get()); |
153 | 0 | nsTextFormatter::ssprintf(out, u"%x", u"foo"); |
154 | 0 | EXPECT_STREQ("foo", NS_ConvertUTF16toUTF8(out).get()); |
155 | 0 | #endif |
156 | 0 | } |
157 | | |
158 | | TEST(TextFormatterTestMismatch, format_s) |
159 | 0 | { |
160 | 0 | nsString out; |
161 | 0 | #ifndef DEBUG |
162 | 0 | nsTextFormatter::ssprintf(out, u"%s", int(-1)); |
163 | 0 | EXPECT_STREQ("-1", NS_ConvertUTF16toUTF8(out).get()); |
164 | 0 | nsTextFormatter::ssprintf(out, u"%s", uint32_t(-1)); |
165 | 0 | EXPECT_STREQ("4294967295", NS_ConvertUTF16toUTF8(out).get()); |
166 | 0 | nsTextFormatter::ssprintf(out, u"%s", float(3.5)); |
167 | 0 | EXPECT_STREQ("3.5", NS_ConvertUTF16toUTF8(out).get()); |
168 | 0 | #endif |
169 | 0 | // just for completeness, this is our format, and works |
170 | 0 | nsTextFormatter::ssprintf(out, u"%s", "foo"); |
171 | 0 | EXPECT_STREQ("foo", NS_ConvertUTF16toUTF8(out).get()); |
172 | 0 | #ifndef DEBUG |
173 | 0 | nsTextFormatter::ssprintf(out, u"%s", u"foo"); |
174 | 0 | EXPECT_STREQ("foo", NS_ConvertUTF16toUTF8(out).get()); |
175 | 0 | #endif |
176 | 0 | } |
177 | | |
178 | | TEST(TextFormatterTestMismatch, format_S) |
179 | 0 | { |
180 | 0 | nsString out; |
181 | 0 | #ifndef DEBUG |
182 | 0 | nsTextFormatter::ssprintf(out, u"%S", int32_t(-1)); |
183 | 0 | EXPECT_STREQ("-1", NS_ConvertUTF16toUTF8(out).get()); |
184 | 0 | nsTextFormatter::ssprintf(out, u"%S", uint32_t(-1)); |
185 | 0 | EXPECT_STREQ("4294967295", NS_ConvertUTF16toUTF8(out).get()); |
186 | 0 | nsTextFormatter::ssprintf(out, u"%S", float(3.5)); |
187 | 0 | EXPECT_STREQ("3.5", NS_ConvertUTF16toUTF8(out).get()); |
188 | 0 | nsTextFormatter::ssprintf(out, u"%S", "foo"); |
189 | 0 | EXPECT_STREQ("foo", NS_ConvertUTF16toUTF8(out).get()); |
190 | 0 | #endif |
191 | 0 | // just for completeness, this is our format, and works |
192 | 0 | nsTextFormatter::ssprintf(out, u"%S", u"foo"); |
193 | 0 | EXPECT_STREQ("foo", NS_ConvertUTF16toUTF8(out).get()); |
194 | 0 | } |
195 | | |
196 | | TEST(TextFormatterTestMismatch, format_c) |
197 | 0 | { |
198 | 0 | nsString out; |
199 | 0 | nsTextFormatter::ssprintf(out, u"%c", int32_t(-1)); |
200 | 0 | EXPECT_EQ(1u, out.Length()); |
201 | 0 | EXPECT_EQ((uint16_t)-1, out.CharAt(0)); // not useful for humans :-/ |
202 | 0 | nsTextFormatter::ssprintf(out, u"%c", uint32_t(-1)); |
203 | 0 | EXPECT_EQ(1u, out.Length()); |
204 | 0 | EXPECT_EQ((uint16_t)-1, out.CharAt(0)); // not useful for humans :-/ |
205 | 0 | #ifndef DEBUG |
206 | 0 | nsTextFormatter::ssprintf(out, u"%c", float(3.5)); |
207 | 0 | EXPECT_STREQ("3.5", NS_ConvertUTF16toUTF8(out).get()); |
208 | 0 | nsTextFormatter::ssprintf(out, u"%c", "foo"); |
209 | 0 | EXPECT_STREQ("foo", NS_ConvertUTF16toUTF8(out).get()); |
210 | 0 | nsTextFormatter::ssprintf(out, u"%c", u"foo"); |
211 | 0 | EXPECT_STREQ("foo", NS_ConvertUTF16toUTF8(out).get()); |
212 | 0 | #endif |
213 | 0 |
|
214 | 0 | // just for completeness, this is our format, and works |
215 | 0 | nsTextFormatter::ssprintf(out, u"%c", 'c'); |
216 | 0 | EXPECT_EQ(1u, out.Length()); |
217 | 0 | EXPECT_EQ(u'c', out.CharAt(0)); |
218 | 0 | nsTextFormatter::ssprintf(out, u"%c", u'c'); |
219 | 0 | EXPECT_EQ(1u, out.Length()); |
220 | 0 | EXPECT_EQ(u'c', out.CharAt(0)); |
221 | 0 | } |
222 | | |
223 | | TEST(TextFormatterTestResults, Tests) |
224 | 0 | { |
225 | 0 | char16_t buf[10]; |
226 | 0 |
|
227 | 0 | EXPECT_EQ(nsTextFormatter::snprintf(buf, 10, u"%s", "more than 10 characters"), 9u); |
228 | 0 | EXPECT_EQ(buf[9], '\0'); |
229 | 0 | EXPECT_STREQ("more than", NS_ConvertUTF16toUTF8(buf).get()); |
230 | 0 |
|
231 | 0 | nsString out; |
232 | 0 | nsTextFormatter::ssprintf(out, u"%s", "more than 10 characters"); |
233 | 0 | // The \0 isn't written here. |
234 | 0 | EXPECT_EQ(out.Length(), 23u); |
235 | 0 | } |