summaryrefslogtreecommitdiffstats
path: root/xpcom/tests/gtest/TestTextFormatter.cpp
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
commit36d22d82aa202bb199967e9512281e9a53db42c9 (patch)
tree105e8c98ddea1c1e4784a60a5a6410fa416be2de /xpcom/tests/gtest/TestTextFormatter.cpp
parentInitial commit. (diff)
downloadfirefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz
firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'xpcom/tests/gtest/TestTextFormatter.cpp')
-rw-r--r--xpcom/tests/gtest/TestTextFormatter.cpp237
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);
+}