File indexing completed on 2024-05-26 04:59:41
0001 /* 0002 SPDX-FileCopyrightText: 2020-2022 Mladen Milinkovic <max@smoothware.net> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "richdocumenttest.h" 0008 0009 #include "helpers/common.h" 0010 0011 #include <QDebug> 0012 #include <QRegularExpression> 0013 #include <QTest> 0014 #include <QTextDocumentFragment> 0015 0016 using namespace SubtitleComposer; 0017 0018 enum Format { 0019 Plain = 1, 0020 Html = 2, 0021 Both = Plain | Html 0022 }; 0023 Q_DECLARE_METATYPE(Format) 0024 0025 void 0026 RichDocumentTest::testCursor() 0027 { 0028 const QString backslashes = $("oXXo"); 0029 doc.setHtml(backslashes); 0030 QTextCursor c(&doc); 0031 QEXPECT_FAIL("", "Already at doc Start", Continue); 0032 QVERIFY(c.movePosition(QTextCursor::Start)); 0033 QVERIFY(c.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, 1)); 0034 QCOMPARE(c.selectedText(), $("o")); 0035 QEXPECT_FAIL("", "Dunno why... some internal anchor == position?", Continue); 0036 QVERIFY(c.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 2)); 0037 c.clearSelection(); 0038 QVERIFY(c.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 2)); 0039 QVERIFY(c.movePosition(QTextCursor::End, QTextCursor::KeepAnchor)); 0040 QCOMPARE(c.selectedText(), $("o")); 0041 } 0042 0043 void 0044 RichDocumentTest::testHtml_data() 0045 { 0046 QTest::addColumn<QString>("html"); 0047 QTest::addColumn<QString>("htmlOut"); 0048 QTest::addColumn<QString>("textOut"); 0049 0050 QTest::newRow("bold styles") 0051 << "<p>It has <b>bold</b> and <strong>strong</strong> styles.</p>" 0052 << "It has <b>bold</b> and <b>strong</b> styles." 0053 << "It has bold and strong styles."; 0054 QTest::newRow("italic styles") 0055 << "<div>It has <i>italic</i> and <em>em</em> styles.</div>" 0056 << "It has <i>italic</i> and <i>em</i> styles." 0057 << "It has italic and em styles."; 0058 QTest::newRow("underline/strikethrough styles") 0059 << "<span>It has <u>underline</u> and <s>strike</s> styles.</span>" 0060 << "It has <u>underline</u> and <s>strike</s> styles." 0061 << "It has underline and strike styles."; 0062 QTest::newRow("color styles") 0063 << "<p>Try <font color=\"red\">red</font> and <font color=\"black\">black</font> and <span style=\"color:blue\">blue</span> color.</p>" 0064 << "Try <font color=#ff0000>red</font> and <font color=#000000>black</font> and <font color=#0000ff>blue</font> color." 0065 << "Try red and black and blue color."; 0066 QTest::newRow("nested color styles") 0067 << "<p><span style=\"color:blue\">Try <font color=\"red\">red</font> and <font color=\"black\">black</font> and blue</span> color.</p>" 0068 << "<font color=#0000ff>Try </font><font color=#ff0000>red</font><font color=#0000ff> and </font><font color=#000000>black</font><font color=#0000ff> and blue</font> color." 0069 << "Try red and black and blue color."; 0070 QTest::newRow("unicode literal") 0071 << "An unicode ♪ char." 0072 << "An unicode \u266A char." 0073 << "An unicode \u266A char."; 0074 QTest::newRow("misc tags, breaks etc") 0075 << "<p>A non breakable space. " 0076 "A newline.\n" 0077 "A line break.<br>" 0078 "And a</p><p>different paragraph</p>" 0079 "and some <p>unclosed and bad</div> <b><i><u><s>tags." 0080 << "A non\u00A0breakable space. " 0081 "A newline.<br>\n" 0082 "A line break.<br>\n" 0083 "And a<br>\ndifferent paragraph<br>\n" 0084 "and some <br>\nunclosed and bad <b><i><u><s>tags.</b></i></u></s>" 0085 << "A non breakable space. " 0086 "A newline.\n" 0087 "A line break.\n" 0088 "And a\ndifferent paragraph\n" 0089 "and some \nunclosed and bad tags."; 0090 QTest::newRow("paragraph break") 0091 << "<p>paragraph text</p>new line" 0092 << "paragraph text<br>\nnew line" 0093 << "paragraph text\nnew line"; 0094 } 0095 0096 void 0097 RichDocumentTest::testHtml() 0098 { 0099 QFETCH(QString, html); 0100 QFETCH(QString, htmlOut); 0101 QFETCH(QString, textOut); 0102 0103 doc.setHtml(html); 0104 QCOMPARE(doc.toHtml(), htmlOut); 0105 QCOMPARE(doc.toPlainText(), textOut); 0106 0107 doc.setHtml(htmlOut); 0108 QCOMPARE(doc.toHtml(), htmlOut); 0109 QCOMPARE(doc.toPlainText(), textOut); 0110 } 0111 0112 void 0113 RichDocumentTest::testRegExpReplace_data() 0114 { 0115 QTest::addColumn<Format>("inType"); 0116 QTest::addColumn<QString>("input"); 0117 QTest::addColumn<QRegularExpression>("re"); 0118 QTest::addColumn<Format>("repType"); 0119 QTest::addColumn<QString>("replacement"); 0120 QTest::addColumn<QString>("expected"); 0121 0122 QTest::newRow("t1") 0123 << Plain << $("xx12xx345xx6xx7xx") 0124 << RE$("x+") 0125 << Plain << QString() 0126 << QString(); 0127 QTest::newRow("t2") 0128 << Plain << $("xx12xx345xx6xx7xx") 0129 << RE$("x+") 0130 << Plain << $("y") 0131 << QString(); 0132 QTest::newRow("t3") 0133 << Plain << $("xx12xx345xx6xx7xx") 0134 << RE$("((6x)|x+)") 0135 << Plain << $("\\2") 0136 << QString(); 0137 QTest::newRow("t4") 0138 << Plain << $("xx12xx345xx6xx7xx") 0139 << RE$("((6x)|x+)") 0140 << Plain << $("o\\2o") 0141 << QString(); 0142 QTest::newRow("t5") 0143 << Plain << $("xx12xx345xx6xx7xx") 0144 << RE$("((\\d)x+)+") 0145 << Plain << $("o\\2o") 0146 << QString(); 0147 QTest::newRow("swaps") 0148 << Plain << $("aa12bb345cc6xx7yy") 0149 << RE$("([a-z]+)\\d+([a-z]+)") 0150 << Plain << $("\\2 swapped \\1") 0151 << QString(); 0152 // these are failing cause replacer is not very good with replacing tags yet 0153 // QTest::newRow("styles1") 0154 // << Html << $("am<b>az</b>ing su<i>per</i> <u>stuff</u>") 0155 // << RE$("\\b(\\w+)\\b") 0156 // << Plain << $("X\\1X") 0157 // << $("Xam<b>az</b>ingX Xsu<i>perX</i> <u>XstuffX</u>"); 0158 // QTest::newRow("styles2") 0159 // << Html << $("am<b>az</b>ing su<i>per</i> <u>stuff</u>") 0160 // << RE$("\\b\\w+\\b") 0161 // << Plain << $("word") 0162 // << $("word word <u>word</u>"); 0163 } 0164 0165 void 0166 RichDocumentTest::testRegExpReplace() 0167 { 0168 QFETCH(Format, inType); 0169 QFETCH(QString, input); 0170 QFETCH(QRegularExpression, re); 0171 QFETCH(Format, repType); 0172 QFETCH(QString, replacement); 0173 QFETCH(QString, expected); 0174 0175 if(inType == Plain) 0176 doc.setPlainText(input, true); 0177 else 0178 doc.setHtml(input, true); 0179 0180 if(expected.isEmpty()) 0181 expected = QString(input).replace(re, replacement); 0182 0183 if(inType == Plain && repType == Plain) { 0184 doc.replace(re, replacement, false); 0185 QCOMPARE(doc.toPlainText(), expected); 0186 } 0187 0188 doc.undo(); 0189 doc.replace(re, replacement, true); 0190 QString docOut = inType == Plain && repType == Plain ? doc.toPlainText() : doc.toHtml(); 0191 QCOMPARE(docOut, expected); 0192 } 0193 0194 void 0195 RichDocumentTest::testIndexReplace_data() 0196 { 0197 QTest::addColumn<Format>("inType"); 0198 QTest::addColumn<QString>("input"); 0199 QTest::addColumn<int>("index"); 0200 QTest::addColumn<int>("length"); 0201 QTest::addColumn<Format>("repType"); 0202 QTest::addColumn<QString>("replacement"); 0203 QTest::addColumn<QString>("expected"); 0204 0205 QTest::newRow("start") 0206 << Plain << $("xx12xx345xx6xx7xx") 0207 << 0 << 4 0208 << Plain << $("YYY") 0209 << $("YYYxx345xx6xx7xx"); 0210 QTest::newRow("middle") 0211 << Plain << $("xx12xx345xx6xx7xx") 0212 << 6 << 3 0213 << Plain << $("YYY") 0214 << $("xx12xxYYYxx6xx7xx"); 0215 QTest::newRow("end") 0216 << Plain << $("xx12xx345xx6xx7xx") 0217 << 12 << 5 0218 << Plain << $("YYY") 0219 << $("xx12xx345xx6YYY"); 0220 } 0221 0222 void 0223 RichDocumentTest::testIndexReplace() 0224 { 0225 QFETCH(Format, inType); 0226 QFETCH(QString, input); 0227 QFETCH(int, index); 0228 QFETCH(int, length); 0229 QFETCH(Format, repType); 0230 QFETCH(QString, replacement); 0231 QFETCH(QString, expected); 0232 0233 if(inType == Plain) 0234 doc.setPlainText(input, true); 0235 else 0236 doc.setHtml(input, true); 0237 0238 if(expected.isEmpty()) 0239 expected = QString(input).replace(index, length, replacement); 0240 0241 if(inType == Plain && repType == Plain) { 0242 doc.replace(index, length, replacement); 0243 QCOMPARE(doc.toPlainText(), expected); 0244 } 0245 0246 doc.undo(); 0247 doc.replace(index, length, replacement); 0248 QString docOut = inType == Plain && repType == Plain ? doc.toPlainText() : doc.toHtml(); 0249 QCOMPARE(docOut, expected); 0250 } 0251 0252 void 0253 RichDocumentTest::testCleanupSpaces_data() 0254 { 0255 QTest::addColumn<Format>("inType"); 0256 QTest::addColumn<QString>("input"); 0257 QTest::addColumn<QString>("expected"); 0258 0259 QTest::newRow("t1") << Html 0260 << $("♪ It <b>\t \t seems </b><i>\t today<br>that</i> all <i> \t you</i> see ♪") 0261 << $("\u266A It seems today\nthat all you see \u266A"); 0262 QTest::newRow("t2") << Plain 0263 << $("\n\n \t This \t is\tsome \t \n \t \n\t \t\n\n \t good subtitle\t\n\ttext. \t") 0264 << $("This is some\ngood subtitle\ntext."); 0265 QTest::newRow("t3") << Plain 0266 << $(" \t \nline text\n \t ") 0267 << $("line text"); 0268 QTest::newRow("t4") << Html 0269 << $(" \t <br> <p>line text</p><p>\n \t </p><div><br> <br></div>") 0270 << $("line text"); 0271 } 0272 0273 void 0274 RichDocumentTest::testCleanupSpaces() 0275 { 0276 QFETCH(Format, inType); 0277 QFETCH(QString, input); 0278 QFETCH(QString, expected); 0279 0280 if(inType == Plain) 0281 doc.setPlainText(input); 0282 else 0283 doc.setHtml(input); 0284 doc.cleanupSpaces(); 0285 QCOMPARE(doc.toPlainText(), expected); 0286 } 0287 0288 void 0289 RichDocumentTest::testUpperLower() 0290 { 0291 doc.setPlainText($("some čćžšđ òàùèì lowercase \u266A♪\\!! text")); 0292 doc.toUpper(); 0293 QCOMPARE(doc.toPlainText(), $("SOME ČĆŽŠĐ ÒÀÙÈÌ LOWERCASE \u266A♪\\!! TEXT")); 0294 doc.toLower(); 0295 QCOMPARE(doc.toPlainText(), $("some čćžšđ òàùèì lowercase \u266A♪\\!! text")); 0296 } 0297 0298 void 0299 RichDocumentTest::testSentence_data() 0300 { 0301 QTest::addColumn<bool>("sentenceStart"); 0302 QTest::addColumn<QString>("input"); 0303 QTest::addColumn<QString>("expected"); 0304 0305 QTest::newRow("t1") << true 0306 << $("begINNING of ♪ some \t \u266A SENTENCE,") 0307 << $("Beginning of ♪ some \t \u266A sentence,"); 0308 QTest::newRow("t2") << false 0309 << $("Which CONTINUES? to finish¿\nthe SENTENCE") 0310 << $("which continues? To finish¿\nThe sentence"); 0311 QTest::newRow("t3") << false 0312 << $("BREAKS: LINE. AND PUP'S ENDS HERE!") 0313 << $("breaks: line. And pup's ends here!"); 0314 } 0315 0316 void 0317 RichDocumentTest::testSentence() 0318 { 0319 QFETCH(bool, sentenceStart); 0320 QFETCH(QString, input); 0321 QFETCH(QString, expected); 0322 0323 doc.setPlainText(input); 0324 doc.toSentenceCase(&sentenceStart); 0325 QCOMPARE(doc.toPlainText(), expected); 0326 } 0327 0328 void 0329 RichDocumentTest::testTitle_data() 0330 { 0331 QTest::addColumn<bool>("sentenceStart"); 0332 QTest::addColumn<QString>("input"); 0333 QTest::addColumn<QString>("expected"); 0334 0335 QTest::newRow("t1") << true 0336 << $("begINNING of ♪ s-o-m-e \t \u266A SENTENCE,") 0337 << $("Beginning Of ♪ S-o-m-e \t \u266A Sentence,"); 0338 QTest::newRow("t2") << false 0339 << $("Whi_ch CONT:INUES? to finish¿\nthe SENTENCE") 0340 << $("Whi_ch Cont:Inues? To Finish¿\nThe Sentence"); 0341 QTest::newRow("t3") << false 0342 << $("BRE+AKS: LINE. AND PUP'S ENDS HERE!") 0343 << $("Bre+aks: Line. And Pup's Ends Here!"); 0344 } 0345 0346 void 0347 RichDocumentTest::testTitle() 0348 { 0349 QFETCH(bool, sentenceStart); 0350 QFETCH(QString, input); 0351 QFETCH(QString, expected); 0352 0353 doc.setPlainText(input); 0354 doc.toSentenceCase(&sentenceStart, true, true); 0355 QCOMPARE(doc.toPlainText(), expected); 0356 } 0357 0358 void 0359 RichDocumentTest::testClass() 0360 { 0361 QTextCursor *c = doc.undoableCursor(); 0362 doc.setPlainText($("The quick brown fox jumps over the lazy dog")); 0363 QVERIFY(c->movePosition(QTextCursor::Start)); 0364 0365 { 0366 QVERIFY(c->movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 4)); 0367 QVERIFY(c->movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, 11)); 0368 QCOMPARE(c->selectedText(), $("quick brown")); 0369 QTextCharFormat fmt; 0370 fmt.setFontWeight(QFont::Bold); 0371 c->mergeCharFormat(fmt); 0372 QCOMPARE(c->selectedText(), $("quick brown")); 0373 c->clearSelection(); 0374 } 0375 { 0376 QVERIFY(c->movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 5)); 0377 QVERIFY(c->movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, 9)); 0378 QCOMPARE(c->selectedText(), $("brown fox")); 0379 QTextCharFormat fmt; 0380 QSet<QString> classList; 0381 classList.insert($("test-class")); 0382 fmt.setProperty(RichDocument::Class, QVariant::fromValue(classList)); 0383 c->mergeCharFormat(fmt); 0384 QCOMPARE(c->selectedText(), $("brown fox")); 0385 c->clearSelection(); 0386 } 0387 qDebug() << doc.toHtml(); 0388 } 0389 0390 QTEST_MAIN(RichDocumentTest)