1 /*
2 SPDX-FileCopyrightText: 2020 Mladen Milinkovic <max@smoothware.net>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7 #include "richdocumenttest.h"
8
9 #include "helpers/common.h"
10
11 #include <QRegularExpression>
12 #include <QTest>
13 #include <QDebug>
14
15 using namespace SubtitleComposer;
16
17 enum Format {
18 Plain = 1,
19 Html = 2,
20 Both = Plain | Html
21 };
Q_DECLARE_METATYPE(Format)22 Q_DECLARE_METATYPE(Format)
23
24 void
25 RichDocumentTest::testCursor()
26 {
27 const QString backslashes = $("oXXo");
28 doc.setHtml(backslashes);
29 QTextCursor c(&doc);
30 QEXPECT_FAIL("", "Already at doc Start", Continue);
31 QVERIFY(c.movePosition(QTextCursor::Start));
32 QVERIFY(c.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, 1));
33 QCOMPARE(c.selectedText(), $("o"));
34 QEXPECT_FAIL("", "Dunno why... some internal anchor == position?", Continue);
35 QVERIFY(c.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 2));
36 c.clearSelection();
37 QVERIFY(c.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 2));
38 QVERIFY(c.movePosition(QTextCursor::End, QTextCursor::KeepAnchor));
39 QCOMPARE(c.selectedText(), $("o"));
40 }
41
42 void
testHtml_data()43 RichDocumentTest::testHtml_data()
44 {
45 QTest::addColumn<QString>("html");
46 QTest::addColumn<QString>("htmlOut");
47 QTest::addColumn<QString>("textOut");
48
49 QTest::newRow("bold styles")
50 << "<p>It has <b>bold</b> and <strong>strong</strong> styles.</p>"
51 << "It has <b>bold</b> and <b>strong</b> styles."
52 << "It has bold and strong styles.";
53 QTest::newRow("italic styles")
54 << "<div>It has <i>italic</i> and <em>em</em> styles.</div>"
55 << "It has <i>italic</i> and <i>em</i> styles."
56 << "It has italic and em styles.";
57 QTest::newRow("underline/strikethrough styles")
58 << "<span>It has <u>underline</u> and <s>strike</s> styles.</span>"
59 << "It has <u>underline</u> and <s>strike</s> styles."
60 << "It has underline and strike styles.";
61 QTest::newRow("color styles")
62 << "<p>Try <font color=\"red\">red</font> and <font color=\"black\">black</font> and <span style=\"color:blue\">blue</span> color.</p>"
63 << "Try <font color=#ff0000>red</font> and <font color=#000000>black</font> and <font color=#0000ff>blue</font> color."
64 << "Try red and black and blue color.";
65 QTest::newRow("unicode literal")
66 << "An unicode ♪ char."
67 << "An unicode \u266A char."
68 << "An unicode \u266A char.";
69 QTest::newRow("misc tags, breaks etc")
70 << "<p>A non breakable space. "
71 "A newline.\n"
72 "A line break.<br>"
73 "And a</p><p>different paragraph</p>"
74 "and some <p>unclosed and bad</div> <b><i><u><s>tags."
75 << "A non\u00A0breakable space. "
76 "A newline.<br>\n"
77 "A line break.<br>\n"
78 "And a<br>\ndifferent paragraph<br>\n"
79 "and some <br>\nunclosed and bad <b><i><u><s>tags.</b></i></u></s>"
80 << "A non breakable space. "
81 "A newline.\n"
82 "A line break.\n"
83 "And a\ndifferent paragraph\n"
84 "and some \nunclosed and bad tags.";
85 }
86
87 void
testHtml()88 RichDocumentTest::testHtml()
89 {
90 QFETCH(QString, html);
91 QFETCH(QString, htmlOut);
92 QFETCH(QString, textOut);
93
94 doc.setHtml(html);
95 QCOMPARE(doc.toHtml(), htmlOut);
96 QCOMPARE(doc.toPlainText(), textOut);
97
98 doc.setHtml(htmlOut);
99 QCOMPARE(doc.toHtml(), htmlOut);
100 QCOMPARE(doc.toPlainText(), textOut);
101 }
102
103 void
testRegExpReplace_data()104 RichDocumentTest::testRegExpReplace_data()
105 {
106 QTest::addColumn<Format>("inType");
107 QTest::addColumn<QString>("input");
108 QTest::addColumn<QRegularExpression>("re");
109 QTest::addColumn<Format>("repType");
110 QTest::addColumn<QString>("replacement");
111 QTest::addColumn<QString>("expected");
112
113 QTest::newRow("t1")
114 << Plain << $("xx12xx345xx6xx7xx")
115 << RE$("x+")
116 << Plain << QString()
117 << QString();
118 QTest::newRow("t2")
119 << Plain << $("xx12xx345xx6xx7xx")
120 << RE$("x+")
121 << Plain << $("y")
122 << QString();
123 QTest::newRow("t3")
124 << Plain << $("xx12xx345xx6xx7xx")
125 << RE$("((6x)|x+)")
126 << Plain << $("\\2")
127 << QString();
128 QTest::newRow("t4")
129 << Plain << $("xx12xx345xx6xx7xx")
130 << RE$("((6x)|x+)")
131 << Plain << $("o\\2o")
132 << QString();
133 QTest::newRow("t5")
134 << Plain << $("xx12xx345xx6xx7xx")
135 << RE$("((\\d)x+)+")
136 << Plain << $("o\\2o")
137 << QString();
138 QTest::newRow("swaps")
139 << Plain << $("aa12bb345cc6xx7yy")
140 << RE$("([a-z]+)\\d+([a-z]+)")
141 << Plain << $("\\2 swapped \\1")
142 << QString();
143 // these are failing cause replacer is not very good with replacing tags yet
144 // QTest::newRow("styles1")
145 // << Html << $("am<b>az</b>ing su<i>per</i> <u>stuff</u>")
146 // << RE$("\\b(\\w+)\\b")
147 // << Plain << $("X\\1X")
148 // << $("Xam<b>az</b>ingX Xsu<i>perX</i> <u>XstuffX</u>");
149 // QTest::newRow("styles2")
150 // << Html << $("am<b>az</b>ing su<i>per</i> <u>stuff</u>")
151 // << RE$("\\b\\w+\\b")
152 // << Plain << $("word")
153 // << $("word word <u>word</u>");
154 }
155
156 void
testRegExpReplace()157 RichDocumentTest::testRegExpReplace()
158 {
159 QFETCH(Format, inType);
160 QFETCH(QString, input);
161 QFETCH(QRegularExpression, re);
162 QFETCH(Format, repType);
163 QFETCH(QString, replacement);
164 QFETCH(QString, expected);
165
166 if(inType == Plain)
167 doc.setPlainText(input, true);
168 else
169 doc.setHtml(input, true);
170
171 if(expected.isEmpty())
172 expected = QString(input).replace(re, replacement);
173
174 if(inType == Plain && repType == Plain) {
175 doc.replace(re, replacement, false);
176 QCOMPARE(doc.toPlainText(), expected);
177 }
178
179 doc.undo();
180 doc.replace(re, replacement, true);
181 QString docOut = inType == Plain && repType == Plain ? doc.toPlainText() : doc.toHtml();
182 QCOMPARE(docOut, expected);
183 }
184
185 void
testIndexReplace_data()186 RichDocumentTest::testIndexReplace_data()
187 {
188 QTest::addColumn<Format>("inType");
189 QTest::addColumn<QString>("input");
190 QTest::addColumn<int>("index");
191 QTest::addColumn<int>("length");
192 QTest::addColumn<Format>("repType");
193 QTest::addColumn<QString>("replacement");
194 QTest::addColumn<QString>("expected");
195
196 QTest::newRow("start")
197 << Plain << $("xx12xx345xx6xx7xx")
198 << 0 << 4
199 << Plain << $("YYY")
200 << $("YYYxx345xx6xx7xx");
201 QTest::newRow("middle")
202 << Plain << $("xx12xx345xx6xx7xx")
203 << 6 << 3
204 << Plain << $("YYY")
205 << $("xx12xxYYYxx6xx7xx");
206 QTest::newRow("end")
207 << Plain << $("xx12xx345xx6xx7xx")
208 << 12 << 5
209 << Plain << $("YYY")
210 << $("xx12xx345xx6YYY");
211 }
212
213 void
testIndexReplace()214 RichDocumentTest::testIndexReplace()
215 {
216 QFETCH(Format, inType);
217 QFETCH(QString, input);
218 QFETCH(int, index);
219 QFETCH(int, length);
220 QFETCH(Format, repType);
221 QFETCH(QString, replacement);
222 QFETCH(QString, expected);
223
224 if(inType == Plain)
225 doc.setPlainText(input, true);
226 else
227 doc.setHtml(input, true);
228
229 if(expected.isEmpty())
230 expected = QString(input).replace(index, length, replacement);
231
232 if(inType == Plain && repType == Plain) {
233 doc.replace(index, length, replacement);
234 QCOMPARE(doc.toPlainText(), expected);
235 }
236
237 doc.undo();
238 doc.replace(index, length, replacement);
239 QString docOut = inType == Plain && repType == Plain ? doc.toPlainText() : doc.toHtml();
240 QCOMPARE(docOut, expected);
241 }
242
243 void
testCleanupSpaces_data()244 RichDocumentTest::testCleanupSpaces_data()
245 {
246 QTest::addColumn<Format>("inType");
247 QTest::addColumn<QString>("input");
248 QTest::addColumn<QString>("expected");
249
250 QTest::newRow("t1") << Html
251 << $("♪ It <b>\t \t seems </b><i>\t today<br>that</i> all <i> \t you</i> see ♪")
252 << $("\u266A It seems today\nthat all you see \u266A");
253 QTest::newRow("t2") << Plain
254 << $("\n\n \t This \t is\tsome \t \n \t \n\t \t\n\n \t good subtitle\t\n\ttext. \t")
255 << $("This is some\ngood subtitle\ntext.");
256 QTest::newRow("t3") << Plain
257 << $(" \t \nline text\n \t ")
258 << $("line text");
259 QTest::newRow("t4") << Html
260 << $(" \t <br> <p>line text</p><p>\n \t </p><div><br> <br></div>")
261 << $("line text");
262 }
263
264 void
testCleanupSpaces()265 RichDocumentTest::testCleanupSpaces()
266 {
267 QFETCH(Format, inType);
268 QFETCH(QString, input);
269 QFETCH(QString, expected);
270
271 if(inType == Plain)
272 doc.setPlainText(input);
273 else
274 doc.setHtml(input);
275 doc.cleanupSpaces();
276 QCOMPARE(doc.toPlainText(), expected);
277 }
278
279 void
testUpperLower()280 RichDocumentTest::testUpperLower()
281 {
282 doc.setPlainText($("some čćžšđ òàùèì lowercase \u266A♪\\!! text"));
283 doc.toUpper();
284 QCOMPARE(doc.toPlainText(), $("SOME ČĆŽŠĐ ÒÀÙÈÌ LOWERCASE \u266A♪\\!! TEXT"));
285 doc.toLower();
286 QCOMPARE(doc.toPlainText(), $("some čćžšđ òàùèì lowercase \u266A♪\\!! text"));
287 }
288
289 void
testSentence_data()290 RichDocumentTest::testSentence_data()
291 {
292 QTest::addColumn<bool>("sentenceStart");
293 QTest::addColumn<QString>("input");
294 QTest::addColumn<QString>("expected");
295
296 QTest::newRow("t1") << true
297 << $("begINNING of ♪ some \t \u266A SENTENCE,")
298 << $("Beginning of ♪ some \t \u266A sentence,");
299 QTest::newRow("t2") << false
300 << $("Which CONTINUES? to finish¿\nthe SENTENCE")
301 << $("which continues? To finish¿\nThe sentence");
302 QTest::newRow("t3") << false
303 << $("BREAKS: LINE. AND PUP'S ENDS HERE!")
304 << $("breaks: line. And pup's ends here!");
305 }
306
307 void
testSentence()308 RichDocumentTest::testSentence()
309 {
310 QFETCH(bool, sentenceStart);
311 QFETCH(QString, input);
312 QFETCH(QString, expected);
313
314 doc.setPlainText(input);
315 doc.toSentenceCase(&sentenceStart);
316 QCOMPARE(doc.toPlainText(), expected);
317 }
318
319 void
testTitle_data()320 RichDocumentTest::testTitle_data()
321 {
322 QTest::addColumn<bool>("sentenceStart");
323 QTest::addColumn<QString>("input");
324 QTest::addColumn<QString>("expected");
325
326 QTest::newRow("t1") << true
327 << $("begINNING of ♪ s-o-m-e \t \u266A SENTENCE,")
328 << $("Beginning Of ♪ S-o-m-e \t \u266A Sentence,");
329 QTest::newRow("t2") << false
330 << $("Whi_ch CONT:INUES? to finish¿\nthe SENTENCE")
331 << $("Whi_ch Cont:Inues? To Finish¿\nThe Sentence");
332 QTest::newRow("t3") << false
333 << $("BRE+AKS: LINE. AND PUP'S ENDS HERE!")
334 << $("Bre+aks: Line. And Pup's Ends Here!");
335 }
336
337 void
testTitle()338 RichDocumentTest::testTitle()
339 {
340 QFETCH(bool, sentenceStart);
341 QFETCH(QString, input);
342 QFETCH(QString, expected);
343
344 doc.setPlainText(input);
345 doc.toSentenceCase(&sentenceStart, true, true);
346 QCOMPARE(doc.toPlainText(), expected);
347 }
348
349 QTEST_GUILESS_MAIN(RichDocumentTest)
350