File indexing completed on 2024-05-12 08:34:46
0001 /* 0002 This file is part of KDevelop 0003 Copyright 2009 Niko Sams <niko.sams@gmail.com> 0004 0005 This library is free software; you can redistribute it and/or 0006 modify it under the terms of the GNU Library General Public 0007 License version 2 as published by the Free Software Foundation. 0008 0009 This library is distributed in the hope that it will be useful, 0010 but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 Library General Public License for more details. 0013 0014 You should have received a copy of the GNU Library General Public License 0015 along with this library; see the file COPYING.LIB. If not, write to 0016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0017 Boston, MA 02110-1301, USA. 0018 */ 0019 0020 #include "parsertest.h" 0021 0022 #include <QDebug> 0023 #include <QTest> 0024 0025 #include "../parsesession.h" 0026 #include "cssdebugvisitor.h" 0027 #include "../editorintegrator.h" 0028 #include "../htmlparser.h" 0029 0030 0031 QTEST_MAIN(Css::TestParser) 0032 0033 namespace Css 0034 { 0035 0036 void TestParser::parser_data() 0037 { 0038 QTest::addColumn<QString>("contents"); 0039 0040 QTest::newRow("one declaration without semicolon") << "body{color:red}"; 0041 QTest::newRow("one declaration with semicolon") << "body{color:red;}"; 0042 QTest::newRow("selector element") << "body{}"; 0043 QTest::newRow("selector class") << ".foo{}"; 0044 QTest::newRow("selector element.class") << "body.foo{}"; 0045 QTest::newRow("selector star") << "*{}"; 0046 QTest::newRow("selector star.class") << "*.foo{}"; 0047 QTest::newRow("selector element attribute1") << "body[foo]{}"; 0048 QTest::newRow("selector element attribute2") << "body[foo~=bar]{}"; 0049 QTest::newRow("selector element attribute3") << "body[foo|=bar]{}"; 0050 QTest::newRow("selector element pseudoclass") << "body:hover{}"; 0051 QTest::newRow("selector element pseudoclass function") << "body:lang(no){}"; 0052 QTest::newRow("selector element pseudoclass nth-child1") << "body:nth-child(even){}"; 0053 QTest::newRow("selector element pseudoclass nth-child2") << "body:nth-child(4){}"; 0054 QTest::newRow("selector element pseudoclass nth-child3") << "body:nth-child(5n+2){}"; 0055 QTest::newRow("selector element pseudoclass selection") << "body::selection{}"; 0056 QTest::newRow("declaration with px term") << "body{width:100px;}"; 0057 QTest::newRow("declaration with em term") << "body{width:5em;}"; 0058 QTest::newRow("declaration with none term") << "body{border:none;}"; 0059 QTest::newRow("declaration with negative px term") << "body{width:-100px;}"; 0060 QTest::newRow("declaration with positive px term") << "body{width:+100px;}"; 0061 QTest::newRow("declaration with url term1") << "body{background-image:url(http://example.com/foo.png);}"; 0062 QTest::newRow("declaration with url term2") << "body{background-image:url(/foo.png);}"; 0063 QTest::newRow("declaration hex color term1") << "body{color:#ff0000;}"; 0064 QTest::newRow("declaration hex color term2") << "body{color:#f00;}"; 0065 QTest::newRow("declaration with multipe px terms") << "body{border-width:1px 2px 3px 4px;}"; 0066 QTest::newRow("charset") << "@charset \"utf-8\"; body{}"; 0067 QTest::newRow("import url") << "@import url(\"foo.css\"); body{}"; 0068 QTest::newRow("import string") << "@import \"foo.css\"; body{}"; 0069 QTest::newRow("two rules") << "h1{}h2{}"; 0070 QTest::newRow("two rules whitespace") << "h1{} h2{}"; 0071 QTest::newRow("missing value") << "body{width:;}"; //todo check for reported error 0072 QTest::newRow("missing value brace") << "body{width:1px;"; //todo check for reported error 0073 QTest::newRow("two selectors with spaces") << " a , b {}"; 0074 QTest::newRow("selector with comma") << " a,{}"; //todo check for reported error 0075 QTest::newRow("selector without declarations") << "a"; //todo check for reported error 0076 QTest::newRow("selector without declarations2") << " a , "; //todo check for reported error 0077 QTest::newRow("selector without declarations3") << " a b "; //todo check for reported error 0078 QTest::newRow("space in declaration") << "body{ color:red;}"; 0079 QTest::newRow("space in declaration") << "body{ color:red}"; 0080 QTest::newRow("id selector") << "#foo{}"; 0081 QTest::newRow("id element selector") << "body#foo{}"; 0082 QTest::newRow("id element selector2") << "#foo a{}"; 0083 QTest::newRow("selector with space") << "a a{}"; 0084 QTest::newRow("empty declaration with space") << "a{ }"; 0085 QTest::newRow("first property no value") << "a{color:;width:0;}"; 0086 QTest::newRow("first property no value2") << "a{color: ; width:0;}"; 0087 QTest::newRow("first property no value no semicolon") << "a{color:width :0;}"; 0088 QTest::newRow("first property no value no semicolon2") << "a{color:width:0;}"; 0089 QTest::newRow("first property no value no semicolon3") << "a{color: width:0;}"; 0090 QTest::newRow("first property no value no semicolon4") << "a { color : width : 0 ; }"; 0091 QTest::newRow("rgb value") << "a { color: rgb(1,2,3); }"; 0092 QTest::newRow("rgb value2") << "a { color: rgb(1%,2%,3%); }"; 0093 QTest::newRow("rgb value3") << "a { color: rgb(255,0,0); }"; 0094 QTest::newRow("rgba value") << "a { color: rgba(255,0,0,127); }"; 0095 QTest::newRow("missing closing brace") << "body{font-w"; 0096 QTest::newRow("invalid character in class name") << ".$cssClass .submitWrapper {\n float: right;\n margin-top: -47px;\n}"; 0097 QTest::newRow("custom function in value") << " p { filter: alpha(opacity=0); }"; 0098 } 0099 0100 void TestParser::parser() 0101 { 0102 QFETCH(QString, contents); 0103 0104 ParseSession session; 0105 session.setContents(contents); 0106 StartAst* ast = nullptr; 0107 QVERIFY(session.parse(&ast)); 0108 DebugVisitor debugVisitor(session.tokenStream(), session.contents()); 0109 debugVisitor.visitStart(ast); 0110 } 0111 0112 void TestParser::multiline() 0113 { 0114 ParseSession session; 0115 session.setContents("body{color:red}\nbody{color:blue}"); 0116 // 012345678901234 01234567890123456 0117 // 0 1 0 1 0118 StartAst* ast = nullptr; 0119 QVERIFY(session.parse(&ast)); 0120 DebugVisitor debugVisitor(session.tokenStream(), session.contents()); 0121 RuleAst* el = ast->rules->rulesSequence->at(1)->element; 0122 debugVisitor.visitNode(el); 0123 0124 EditorIntegrator editor; 0125 editor.setParseSession(&session); 0126 qDebug() << editor.findPosition(el->startToken, EditorIntegrator::FrontEdge); 0127 qDebug() << editor.findPosition(el->endToken, EditorIntegrator::BackEdge); 0128 QCOMPARE(editor.findPosition(el->endToken, EditorIntegrator::BackEdge), 0129 KDevelop::CursorInRevision(1, 16)); 0130 } 0131 0132 void TestParser::htmlStyleElement() 0133 { 0134 HtmlParser p; 0135 //0 1 2 3 4 0136 //012345678901234567 890123456 78901234567890123456789 0137 p.setContents("<html><style type=\"text/css\">a{color:red}</style></html>"); 0138 QList<HtmlParser::Part> res = p.parse(); 0139 QCOMPARE(res.count(), 1); 0140 QCOMPARE(res[0].contents, QString("a{color:red}")); 0141 QCOMPARE(res[0].range, KTextEditor::Range(0, 29, 0, 41)); 0142 } 0143 0144 void TestParser::htmlInlineStyle() 0145 { 0146 HtmlParser p; 0147 //0 1 2 3 4 0148 //012345678901234 5678901234 5678901234567890123456789 0149 p.setContents("<html><p style=\"color:red\"></p></html>"); 0150 QList<HtmlParser::Part> res = p.parse(); 0151 QCOMPARE(res.count(), 1); 0152 QCOMPARE(res[0].contents, QString("color:red")); 0153 QCOMPARE(res[0].range, KTextEditor::Range(0, 16, 0, 25)); 0154 QCOMPARE(res[0].tag, QString("p")); 0155 } 0156 0157 void TestParser::htmlInlineStyle2() 0158 { 0159 HtmlParser p; 0160 //0 1 2 3 4 0161 //0123456789012345 6789 01234567 8901234567 890123456789 0162 p.setContents("<html> <div id=\"foo\" style=\"color:red\"></html>"); 0163 QList<HtmlParser::Part> res = p.parse(); 0164 QCOMPARE(res.count(), 1); 0165 QCOMPARE(res[0].contents, QString("color:red")); 0166 QCOMPARE(res[0].range, KTextEditor::Range(0, 29, 0, 38)); 0167 } 0168 0169 void TestParser::htmlInlineStyle3() 0170 { 0171 HtmlParser p; 0172 //0 1 2 3 0173 //0 1 2 0 1 0 0 0174 //0123456789012345 6789 01 2012345 67890123456 7012 3 40123456 0175 p.setContents("<html> <div id=\"foo\" \nstyle=\"color:red;\nabc\"\n></html>"); 0176 QList<HtmlParser::Part> res = p.parse(); 0177 QCOMPARE(res.count(), 1); 0178 QCOMPARE(res[0].contents, QString("color:red;\nabc")); 0179 QCOMPARE(res[0].range, KTextEditor::Range(1, 7, 2, 3)); 0180 } 0181 0182 } 0183