diff options
Diffstat (limited to '')
-rw-r--r-- | xpcom/tests/gtest/TestTextFormatter.cpp | 237 |
1 files changed, 237 insertions, 0 deletions
diff --git a/xpcom/tests/gtest/TestTextFormatter.cpp b/xpcom/tests/gtest/TestTextFormatter.cpp new file mode 100644 index 0000000000..9e3d99a056 --- /dev/null +++ b/xpcom/tests/gtest/TestTextFormatter.cpp @@ -0,0 +1,237 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsTextFormatter.h" +#include "nsString.h" +#include "gtest/gtest.h" + +TEST(TextFormatter, Tests) +{ + nsAutoString fmt(u"%3$s %4$S %1$d %2$d %2$d %3$s"_ns); + char utf8[] = "Hello"; + char16_t ucs2[] = {'W', 'o', 'r', 'l', 'd', + 0x4e00, 0xAc00, 0xFF45, 0x0103, 0x00}; + int d = 3; + + char16_t buf[256]; + nsTextFormatter::snprintf(buf, 256, fmt.get(), d, 333, utf8, ucs2); + nsAutoString out(buf); + + const char16_t* uout = out.get(); + const char16_t expected[] = { + 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64, + 0x4E00, 0xAC00, 0xFF45, 0x0103, 0x20, 0x33, 0x20, 0x33, 0x33, 0x33, 0x20, + 0x33, 0x33, 0x33, 0x20, 0x48, 0x65, 0x6C, 0x6C, 0x6F}; + + for (uint32_t i = 0; i < out.Length(); i++) { + ASSERT_EQ(uout[i], expected[i]); + } + + // Test that an unrecognized escape is passed through. + nsString out2; + nsTextFormatter::ssprintf(out2, u"%1m!", 23); + EXPECT_STREQ("%1m!", NS_ConvertUTF16toUTF8(out2).get()); + + // Treat NULL the same in both %s cases. + nsTextFormatter::ssprintf(out2, u"%s %S", (char*)nullptr, (char16_t*)nullptr); + EXPECT_STREQ("(null) (null)", NS_ConvertUTF16toUTF8(out2).get()); + + nsTextFormatter::ssprintf(out2, u"%lld", INT64_MIN); + EXPECT_STREQ("-9223372036854775808", NS_ConvertUTF16toUTF8(out2).get()); + + // Regression test for bug 1401821. + nsTextFormatter::ssprintf(out2, u"%*.f", 0, 23.2); + EXPECT_STREQ("23", NS_ConvertUTF16toUTF8(out2).get()); +} + +/* + * Check misordered parameters + */ + +TEST(TextFormatterOrdering, orders) +{ + nsString out; + + // plain list + nsTextFormatter::ssprintf(out, u"%S %S %S", u"1", u"2", u"3"); + EXPECT_STREQ("1 2 3", NS_ConvertUTF16toUTF8(out).get()); + + // ordered list + nsTextFormatter::ssprintf(out, u"%2$S %3$S %1$S", u"1", u"2", u"3"); + EXPECT_STREQ("2 3 1", NS_ConvertUTF16toUTF8(out).get()); + + // Mixed ordered list and non-ordered does not work. This shouldn't + // crash (hence the calls to ssprintf) but should fail for for + // snprintf. + nsTextFormatter::ssprintf(out, u"%2S %S %1$S", u"1", u"2", u"3"); + nsTextFormatter::ssprintf(out, u"%S %2$S", u"1", u"2"); + char16_t buffer[1024]; // plenty big + EXPECT_EQ(nsTextFormatter::snprintf(buffer, sizeof(buffer), u"%2S %S %1$S", + u"1", u"2", u"3"), + uint32_t(-1)); + EXPECT_EQ( + nsTextFormatter::snprintf(buffer, sizeof(buffer), u"%S %2$S", u"1", u"2"), + uint32_t(-1)); + + // Referencing an extra param returns empty strings in release. +#ifndef DEBUG + nsTextFormatter::ssprintf(out, u" %2$S ", u"1"); + EXPECT_STREQ(" ", NS_ConvertUTF16toUTF8(out).get()); +#endif + + // Double referencing existing argument works + nsTextFormatter::ssprintf(out, u"%1$S %1$S", u"1"); + EXPECT_STREQ("1 1", NS_ConvertUTF16toUTF8(out).get()); + + // Dropping trailing argument works + nsTextFormatter::ssprintf(out, u" %1$S ", u"1", u"2"); + EXPECT_STREQ(" 1 ", NS_ConvertUTF16toUTF8(out).get()); + + // Dropping leading arguments works + nsTextFormatter::ssprintf(out, u" %2$S ", u"1", u"2"); + EXPECT_STREQ(" 2 ", NS_ConvertUTF16toUTF8(out).get()); + + // Dropping middle arguments works + nsTextFormatter::ssprintf(out, u" %3$S %1$S ", u"1", u"2", u"3"); + EXPECT_STREQ(" 3 1 ", NS_ConvertUTF16toUTF8(out).get()); +} + +/* + * Tests to validate that horrible things don't happen if the passed-in + * variable and the formatter don't match. + */ +TEST(TextFormatterTestMismatch, format_d) +{ + nsString out; + // just for completeness, this is our format, and works + nsTextFormatter::ssprintf(out, u"%d", int(-1)); + EXPECT_STREQ("-1", NS_ConvertUTF16toUTF8(out).get()); + nsTextFormatter::ssprintf(out, u"%d", uint32_t(-1)); + EXPECT_STREQ("4294967295", NS_ConvertUTF16toUTF8(out).get()); +#ifndef DEBUG + nsTextFormatter::ssprintf(out, u"%d", float(3.5)); + EXPECT_STREQ("3.5", NS_ConvertUTF16toUTF8(out).get()); + nsTextFormatter::ssprintf(out, u"%d", "foo"); + EXPECT_STREQ("foo", NS_ConvertUTF16toUTF8(out).get()); + nsTextFormatter::ssprintf(out, u"%d", u"foo"); + EXPECT_STREQ("foo", NS_ConvertUTF16toUTF8(out).get()); +#endif +} + +TEST(TextFormatterTestMismatch, format_u) +{ + nsString out; + nsTextFormatter::ssprintf(out, u"%u", int(-1)); + EXPECT_STREQ("4294967295", NS_ConvertUTF16toUTF8(out).get()); + // just for completeness, this is our format, and works + nsTextFormatter::ssprintf(out, u"%u", uint32_t(-1)); + EXPECT_STREQ("4294967295", NS_ConvertUTF16toUTF8(out).get()); +#ifndef DEBUG + nsTextFormatter::ssprintf(out, u"%u", float(3.5)); + EXPECT_STREQ("3.5", NS_ConvertUTF16toUTF8(out).get()); + nsTextFormatter::ssprintf(out, u"%u", "foo"); + EXPECT_STREQ("foo", NS_ConvertUTF16toUTF8(out).get()); + nsTextFormatter::ssprintf(out, u"%u", u"foo"); + EXPECT_STREQ("foo", NS_ConvertUTF16toUTF8(out).get()); +#endif +} + +TEST(TextFormatterTestMismatch, format_x) +{ + nsString out; + nsTextFormatter::ssprintf(out, u"%x", int32_t(-1)); + EXPECT_STREQ("ffffffff", NS_ConvertUTF16toUTF8(out).get()); + // just for completeness, this is our format, and works + nsTextFormatter::ssprintf(out, u"%x", uint32_t(-1)); + EXPECT_STREQ("ffffffff", NS_ConvertUTF16toUTF8(out).get()); +#ifndef DEBUG + nsTextFormatter::ssprintf(out, u"%x", float(3.5)); + EXPECT_STREQ("3.5", NS_ConvertUTF16toUTF8(out).get()); + nsTextFormatter::ssprintf(out, u"%x", "foo"); + EXPECT_STREQ("foo", NS_ConvertUTF16toUTF8(out).get()); + nsTextFormatter::ssprintf(out, u"%x", u"foo"); + EXPECT_STREQ("foo", NS_ConvertUTF16toUTF8(out).get()); +#endif +} + +TEST(TextFormatterTestMismatch, format_s) +{ + nsString out; +#ifndef DEBUG + nsTextFormatter::ssprintf(out, u"%s", int(-1)); + EXPECT_STREQ("-1", NS_ConvertUTF16toUTF8(out).get()); + nsTextFormatter::ssprintf(out, u"%s", uint32_t(-1)); + EXPECT_STREQ("4294967295", NS_ConvertUTF16toUTF8(out).get()); + nsTextFormatter::ssprintf(out, u"%s", float(3.5)); + EXPECT_STREQ("3.5", NS_ConvertUTF16toUTF8(out).get()); +#endif + // just for completeness, this is our format, and works + nsTextFormatter::ssprintf(out, u"%s", "foo"); + EXPECT_STREQ("foo", NS_ConvertUTF16toUTF8(out).get()); +#ifndef DEBUG + nsTextFormatter::ssprintf(out, u"%s", u"foo"); + EXPECT_STREQ("foo", NS_ConvertUTF16toUTF8(out).get()); +#endif +} + +TEST(TextFormatterTestMismatch, format_S) +{ + nsString out; +#ifndef DEBUG + nsTextFormatter::ssprintf(out, u"%S", int32_t(-1)); + EXPECT_STREQ("-1", NS_ConvertUTF16toUTF8(out).get()); + nsTextFormatter::ssprintf(out, u"%S", uint32_t(-1)); + EXPECT_STREQ("4294967295", NS_ConvertUTF16toUTF8(out).get()); + nsTextFormatter::ssprintf(out, u"%S", float(3.5)); + EXPECT_STREQ("3.5", NS_ConvertUTF16toUTF8(out).get()); + nsTextFormatter::ssprintf(out, u"%S", "foo"); + EXPECT_STREQ("foo", NS_ConvertUTF16toUTF8(out).get()); +#endif + // just for completeness, this is our format, and works + nsTextFormatter::ssprintf(out, u"%S", u"foo"); + EXPECT_STREQ("foo", NS_ConvertUTF16toUTF8(out).get()); +} + +TEST(TextFormatterTestMismatch, format_c) +{ + nsString out; + nsTextFormatter::ssprintf(out, u"%c", int32_t(-1)); + EXPECT_EQ(1u, out.Length()); + EXPECT_EQ((uint16_t)-1, out.CharAt(0)); // not useful for humans :-/ + nsTextFormatter::ssprintf(out, u"%c", uint32_t(-1)); + EXPECT_EQ(1u, out.Length()); + EXPECT_EQ((uint16_t)-1, out.CharAt(0)); // not useful for humans :-/ +#ifndef DEBUG + nsTextFormatter::ssprintf(out, u"%c", float(3.5)); + EXPECT_STREQ("3.5", NS_ConvertUTF16toUTF8(out).get()); + nsTextFormatter::ssprintf(out, u"%c", "foo"); + EXPECT_STREQ("foo", NS_ConvertUTF16toUTF8(out).get()); + nsTextFormatter::ssprintf(out, u"%c", u"foo"); + EXPECT_STREQ("foo", NS_ConvertUTF16toUTF8(out).get()); +#endif + + // just for completeness, this is our format, and works + nsTextFormatter::ssprintf(out, u"%c", 'c'); + EXPECT_EQ(1u, out.Length()); + EXPECT_EQ(u'c', out.CharAt(0)); + nsTextFormatter::ssprintf(out, u"%c", u'c'); + EXPECT_EQ(1u, out.Length()); + EXPECT_EQ(u'c', out.CharAt(0)); +} + +TEST(TextFormatterTestResults, Tests) +{ + char16_t buf[10]; + + EXPECT_EQ( + nsTextFormatter::snprintf(buf, 10, u"%s", "more than 10 characters"), 9u); + EXPECT_EQ(buf[9], '\0'); + EXPECT_STREQ("more than", NS_ConvertUTF16toUTF8(&buf[0]).get()); + + nsString out; + nsTextFormatter::ssprintf(out, u"%s", "more than 10 characters"); + // The \0 isn't written here. + EXPECT_EQ(out.Length(), 23u); +} |