1 | /* |
2 | * Copyright (C) 2010, 2011, Pino Toscano <pino@kde.org> |
3 | * Copyright (C) 2021 Klarälvdalens Datakonsult AB, a KDAB Group company, <info@kdab.com> |
4 | * |
5 | * This program is free software; you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License as published by |
7 | * the Free Software Foundation; either version 2, or (at your option) |
8 | * any later version. |
9 | * |
10 | * This program is distributed in the hope that it will be useful, |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | * GNU General Public License for more details. |
14 | * |
15 | * You should have received a copy of the GNU General Public License |
16 | * along with this program; if not, write to the Free Software |
17 | * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. |
18 | */ |
19 | |
20 | #include <QtTest/QTest> |
21 | |
22 | #include <poppler-qt6.h> |
23 | #include <poppler-private.h> |
24 | |
25 | #include <GlobalParams.h> |
26 | #include "UTF.h" |
27 | |
28 | Q_DECLARE_METATYPE(GooString *) |
29 | Q_DECLARE_METATYPE(Unicode *) |
30 | |
31 | class TestStrings : public QObject |
32 | { |
33 | Q_OBJECT |
34 | |
35 | public: |
36 | explicit TestStrings(QObject *parent = nullptr) : QObject(parent) { } |
37 | |
38 | private slots: |
39 | void initTestCase(); |
40 | void cleanupTestCase(); |
41 | void check_unicodeToQString_data(); |
42 | void check_unicodeToQString(); |
43 | void check_UnicodeParsedString_data(); |
44 | void check_UnicodeParsedString(); |
45 | void check_QStringToUnicodeGooString_data(); |
46 | void check_QStringToUnicodeGooString(); |
47 | void check_QStringToGooString_data(); |
48 | void check_QStringToGooString(); |
49 | |
50 | private: |
51 | GooString *newGooString(const char *s); |
52 | GooString *newGooString(const char *s, int l); |
53 | |
54 | QVector<GooString *> m_gooStrings; |
55 | }; |
56 | |
57 | void TestStrings::initTestCase() |
58 | { |
59 | qRegisterMetaType<GooString *>(typeName: "GooString*" ); |
60 | qRegisterMetaType<Unicode *>(typeName: "Unicode*" ); |
61 | |
62 | globalParams = std::make_unique<GlobalParams>(); |
63 | } |
64 | |
65 | void TestStrings::cleanupTestCase() |
66 | { |
67 | qDeleteAll(c: m_gooStrings); |
68 | |
69 | globalParams.reset(); |
70 | } |
71 | |
72 | void TestStrings::check_unicodeToQString_data() |
73 | { |
74 | QTest::addColumn<Unicode *>(name: "data" ); |
75 | QTest::addColumn<int>(name: "length" ); |
76 | QTest::addColumn<QString>(name: "result" ); |
77 | |
78 | { |
79 | const int l = 1; |
80 | Unicode *u = new Unicode[l]; |
81 | u[0] = int('a'); |
82 | QTest::newRow(dataTag: "a" ) << u << l << QStringLiteral("a" ); |
83 | } |
84 | { |
85 | const int l = 1; |
86 | Unicode *u = new Unicode[l]; |
87 | u[0] = 0x0161; |
88 | QTest::newRow(dataTag: "\u0161" ) << u << l << QStringLiteral("\u0161" ); |
89 | } |
90 | { |
91 | const int l = 2; |
92 | Unicode *u = new Unicode[l]; |
93 | u[0] = int('a'); |
94 | u[1] = int('b'); |
95 | QTest::newRow(dataTag: "ab" ) << u << l << QStringLiteral("ab" ); |
96 | } |
97 | { |
98 | const int l = 2; |
99 | Unicode *u = new Unicode[l]; |
100 | u[0] = int('a'); |
101 | u[1] = 0x0161; |
102 | QTest::newRow(dataTag: "a\u0161" ) << u << l << QStringLiteral("a\u0161" ); |
103 | } |
104 | { |
105 | const int l = 2; |
106 | Unicode *u = new Unicode[l]; |
107 | u[0] = 0x5c01; |
108 | u[1] = 0x9762; |
109 | QTest::newRow(dataTag: "\xe5\xb0\x81\xe9\x9d\xa2" ) << u << l << QStringLiteral("封面" ); |
110 | } |
111 | { |
112 | const int l = 3; |
113 | Unicode *u = new Unicode[l]; |
114 | u[0] = 0x5c01; |
115 | u[1] = 0x9762; |
116 | u[2] = 0x0; |
117 | QTest::newRow(dataTag: "\xe5\xb0\x81\xe9\x9d\xa2 + 0" ) << u << l << QStringLiteral("封面" ); |
118 | } |
119 | { |
120 | const int l = 4; |
121 | Unicode *u = new Unicode[l]; |
122 | u[0] = 0x5c01; |
123 | u[1] = 0x9762; |
124 | u[2] = 0x0; |
125 | u[3] = 0x0; |
126 | QTest::newRow(dataTag: "\xe5\xb0\x81\xe9\x9d\xa2 + two 0" ) << u << l << QStringLiteral("封面" ); |
127 | } |
128 | } |
129 | |
130 | void TestStrings::check_unicodeToQString() |
131 | { |
132 | QFETCH(Unicode *, data); |
133 | QFETCH(int, length); |
134 | QFETCH(QString, result); |
135 | |
136 | QCOMPARE(Poppler::unicodeToQString(data, length), result); |
137 | |
138 | delete[] data; |
139 | } |
140 | |
141 | void TestStrings::check_UnicodeParsedString_data() |
142 | { |
143 | QTest::addColumn<GooString *>(name: "string" ); |
144 | QTest::addColumn<QString>(name: "result" ); |
145 | |
146 | // non-unicode strings |
147 | QTest::newRow(dataTag: "<empty>" ) << newGooString(s: "" ) << QString(); |
148 | QTest::newRow(dataTag: "a" ) << newGooString(s: "a" ) << QStringLiteral("a" ); |
149 | QTest::newRow(dataTag: "ab" ) << newGooString(s: "ab" ) << QStringLiteral("ab" ); |
150 | QTest::newRow(dataTag: "~" ) << newGooString(s: "~" ) << QStringLiteral("~" ); |
151 | QTest::newRow(dataTag: "test string" ) << newGooString(s: "test string" ) << QStringLiteral("test string" ); |
152 | |
153 | // unicode strings |
154 | QTest::newRow(dataTag: "<unicode marks>" ) << newGooString(s: "\xFE\xFF" ) << QString(); |
155 | QTest::newRow(dataTag: "U a" ) << newGooString(s: "\xFE\xFF\0a" , l: 4) << QStringLiteral("a" ); |
156 | QTest::newRow(dataTag: "U ~" ) << newGooString(s: "\xFE\xFF\0~" , l: 4) << QStringLiteral("~" ); |
157 | QTest::newRow(dataTag: "U aa" ) << newGooString(s: "\xFE\xFF\0a\0a" , l: 6) << QStringLiteral("aa" ); |
158 | QTest::newRow(dataTag: "U \xC3\x9F" ) << newGooString(s: "\xFE\xFF\0\xDF" , l: 4) << QStringLiteral("ß" ); |
159 | QTest::newRow(dataTag: "U \xC3\x9F\x61" ) << newGooString(s: "\xFE\xFF\0\xDF\0\x61" , l: 6) << QStringLiteral("ßa" ); |
160 | QTest::newRow(dataTag: "U \xC5\xA1" ) << newGooString(s: "\xFE\xFF\x01\x61" , l: 4) << QStringLiteral("š" ); |
161 | QTest::newRow(dataTag: "U \xC5\xA1\x61" ) << newGooString(s: "\xFE\xFF\x01\x61\0\x61" , l: 6) << QStringLiteral("ša" ); |
162 | QTest::newRow(dataTag: "test string" ) << newGooString(s: "\xFE\xFF\0t\0e\0s\0t\0 \0s\0t\0r\0i\0n\0g" , l: 24) << QStringLiteral("test string" ); |
163 | QTest::newRow(dataTag: "UTF16-LE" ) << newGooString(s: "\xFF\xFE\xDA\x00\x6E\x00\xEE\x00\x63\x00\xF6\x00\x64\x00\xE9\x00\x51\x75" , l: 18) << QStringLiteral("Únîcödé畑" ); |
164 | } |
165 | |
166 | void TestStrings::check_UnicodeParsedString() |
167 | { |
168 | QFETCH(GooString *, string); |
169 | QFETCH(QString, result); |
170 | |
171 | QCOMPARE(Poppler::UnicodeParsedString(string), result); |
172 | } |
173 | |
174 | void TestStrings::check_QStringToUnicodeGooString_data() |
175 | { |
176 | QTest::addColumn<QString>(name: "string" ); |
177 | QTest::addColumn<QByteArray>(name: "result" ); |
178 | |
179 | QTest::newRow(dataTag: "<null>" ) << QString() << QByteArray("" ); |
180 | QTest::newRow(dataTag: "<empty>" ) << QString(QLatin1String("" )) << QByteArray("" ); |
181 | QTest::newRow(dataTag: "a" ) << QStringLiteral("a" ) << QByteArray("\0a" , 2); |
182 | QTest::newRow(dataTag: "ab" ) << QStringLiteral("ab" ) << QByteArray("\0a\0b" , 4); |
183 | QTest::newRow(dataTag: "test string" ) << QStringLiteral("test string" ) << QByteArray("\0t\0e\0s\0t\0 \0s\0t\0r\0i\0n\0g" , 22); |
184 | QTest::newRow(dataTag: "\xC3\x9F" ) << QStringLiteral("ß" ) << QByteArray("\0\xDF" , 2); |
185 | QTest::newRow(dataTag: "\xC3\x9F\x61" ) << QStringLiteral("ßa" ) << QByteArray("\0\xDF\0\x61" , 4); |
186 | } |
187 | |
188 | void TestStrings::check_QStringToUnicodeGooString() |
189 | { |
190 | QFETCH(QString, string); |
191 | QFETCH(QByteArray, result); |
192 | |
193 | GooString *goo = Poppler::QStringToUnicodeGooString(s: string); |
194 | if (string.isEmpty()) { |
195 | QVERIFY(goo->toStr().empty()); |
196 | QCOMPARE(goo->getLength(), 0); |
197 | } else { |
198 | QVERIFY(hasUnicodeByteOrderMark(goo->toStr())); |
199 | QCOMPARE(goo->getLength(), string.length() * 2 + 2); |
200 | QCOMPARE(result, QByteArray::fromRawData(goo->c_str() + 2, goo->getLength() - 2)); |
201 | } |
202 | |
203 | delete goo; |
204 | } |
205 | |
206 | void TestStrings::check_QStringToGooString_data() |
207 | { |
208 | QTest::addColumn<QString>(name: "string" ); |
209 | QTest::addColumn<GooString *>(name: "result" ); |
210 | |
211 | QTest::newRow(dataTag: "<null>" ) << QString() << newGooString(s: "" ); |
212 | QTest::newRow(dataTag: "<empty>" ) << QString(QLatin1String("" )) << newGooString(s: "" ); |
213 | QTest::newRow(dataTag: "a" ) << QStringLiteral("a" ) << newGooString(s: "a" ); |
214 | QTest::newRow(dataTag: "ab" ) << QStringLiteral("ab" ) << newGooString(s: "ab" ); |
215 | } |
216 | |
217 | void TestStrings::check_QStringToGooString() |
218 | { |
219 | QFETCH(QString, string); |
220 | QFETCH(GooString *, result); |
221 | |
222 | GooString *goo = Poppler::QStringToGooString(s: string); |
223 | QCOMPARE(goo->c_str(), result->c_str()); |
224 | |
225 | delete goo; |
226 | } |
227 | |
228 | GooString *TestStrings::newGooString(const char *s) |
229 | { |
230 | GooString *goo = new GooString(s); |
231 | m_gooStrings.append(t: goo); |
232 | return goo; |
233 | } |
234 | |
235 | GooString *TestStrings::newGooString(const char *s, int l) |
236 | { |
237 | GooString *goo = new GooString(s, l); |
238 | m_gooStrings.append(t: goo); |
239 | return goo; |
240 | } |
241 | |
242 | QTEST_GUILESS_MAIN(TestStrings) |
243 | |
244 | #include "check_strings.moc" |
245 | |