1 // Copyright 2020 The PDFium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "core/fxcrt/css/cfx_csssyntaxparser.h"
6
7 #include "testing/gtest/include/gtest/gtest.h"
8
9 // These tests cover the "declaration only" mode of the CSS Syntax Parser
10 // (i.e. inline style="" attribute). The cfx_cssstylesheet_unitttest.cpp
11 // file covers the full-up selector { ... } parsing.
12
TEST(CSSSyntaxParserTest,ParseEmpty)13 TEST(CSSSyntaxParserTest, ParseEmpty) {
14 const wchar_t* input = L"";
15 CFX_CSSSyntaxParser parser(input);
16 parser.SetParseOnlyDeclarations();
17 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kEOS, parser.DoSyntaxParse());
18 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kEOS, parser.DoSyntaxParse());
19 }
20
TEST(CSSSyntaxParserTest,ParseBlank)21 TEST(CSSSyntaxParserTest, ParseBlank) {
22 const wchar_t* input = L" \n\r\t";
23 CFX_CSSSyntaxParser parser(input);
24 parser.SetParseOnlyDeclarations();
25 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kEOS, parser.DoSyntaxParse());
26 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kEOS, parser.DoSyntaxParse());
27 }
28
TEST(CSSSyntaxParserTest,ParseMissingColon)29 TEST(CSSSyntaxParserTest, ParseMissingColon) {
30 const wchar_t* input = L"foo ";
31 CFX_CSSSyntaxParser parser(input);
32 parser.SetParseOnlyDeclarations();
33 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kEOS, parser.DoSyntaxParse());
34 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kEOS, parser.DoSyntaxParse());
35 }
36
TEST(CSSSyntaxParserTest,ParseMissingValue)37 TEST(CSSSyntaxParserTest, ParseMissingValue) {
38 const wchar_t* input = L"foo: ";
39 CFX_CSSSyntaxParser parser(input);
40 parser.SetParseOnlyDeclarations();
41 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kPropertyName, parser.DoSyntaxParse());
42 EXPECT_EQ(L"foo", parser.GetCurrentString());
43 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kEOS, parser.DoSyntaxParse());
44 }
45
TEST(CSSSyntaxParserTest,ParseSingleProp1)46 TEST(CSSSyntaxParserTest, ParseSingleProp1) {
47 const wchar_t* input = L"foo:bar";
48 CFX_CSSSyntaxParser parser(input);
49 parser.SetParseOnlyDeclarations();
50 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kPropertyName, parser.DoSyntaxParse());
51 EXPECT_EQ(L"foo", parser.GetCurrentString());
52 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kPropertyValue,
53 parser.DoSyntaxParse());
54 EXPECT_EQ(L"bar", parser.GetCurrentString());
55 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kEOS, parser.DoSyntaxParse());
56 }
57
TEST(CSSSyntaxParserTest,ParseSingleProp2)58 TEST(CSSSyntaxParserTest, ParseSingleProp2) {
59 const wchar_t* input = L"foo:bar;";
60 CFX_CSSSyntaxParser parser(input);
61 parser.SetParseOnlyDeclarations();
62 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kPropertyName, parser.DoSyntaxParse());
63 EXPECT_EQ(L"foo", parser.GetCurrentString());
64 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kPropertyValue,
65 parser.DoSyntaxParse());
66 EXPECT_EQ(L"bar", parser.GetCurrentString());
67 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kEOS, parser.DoSyntaxParse());
68 }
69
TEST(CSSSyntaxParserTest,ParseMissingColonMultiple)70 TEST(CSSSyntaxParserTest, ParseMissingColonMultiple) {
71 const wchar_t* input = L"foo:bar; baz";
72 CFX_CSSSyntaxParser parser(input);
73 parser.SetParseOnlyDeclarations();
74 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kPropertyName, parser.DoSyntaxParse());
75 EXPECT_EQ(L"foo", parser.GetCurrentString());
76 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kPropertyValue,
77 parser.DoSyntaxParse());
78 EXPECT_EQ(L"bar", parser.GetCurrentString());
79 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kEOS, parser.DoSyntaxParse());
80 }
81
TEST(CSSSyntaxParserTest,ParseMissingPropertyMultiple)82 TEST(CSSSyntaxParserTest, ParseMissingPropertyMultiple) {
83 const wchar_t* input = L"foo:bar; baz: ";
84 CFX_CSSSyntaxParser parser(input);
85 parser.SetParseOnlyDeclarations();
86 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kPropertyName, parser.DoSyntaxParse());
87 EXPECT_EQ(L"foo", parser.GetCurrentString());
88 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kPropertyValue,
89 parser.DoSyntaxParse());
90 EXPECT_EQ(L"bar", parser.GetCurrentString());
91 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kPropertyName, parser.DoSyntaxParse());
92 EXPECT_EQ(L"baz", parser.GetCurrentString());
93 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kEOS, parser.DoSyntaxParse());
94 }
95
TEST(CSSSyntaxParserTest,ParseMultipleProp1)96 TEST(CSSSyntaxParserTest, ParseMultipleProp1) {
97 const wchar_t* input = L"foo : bar; baz : bam";
98 CFX_CSSSyntaxParser parser(input);
99 parser.SetParseOnlyDeclarations();
100 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kPropertyName, parser.DoSyntaxParse());
101 EXPECT_EQ(L"foo", parser.GetCurrentString());
102 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kPropertyValue,
103 parser.DoSyntaxParse());
104 EXPECT_EQ(L"bar", parser.GetCurrentString());
105 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kPropertyName, parser.DoSyntaxParse());
106 EXPECT_EQ(L"baz", parser.GetCurrentString());
107 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kPropertyValue,
108 parser.DoSyntaxParse());
109 EXPECT_EQ(L"bam", parser.GetCurrentString());
110 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kEOS, parser.DoSyntaxParse());
111 }
112
TEST(CSSSyntaxParserTest,ParseMultipleProp2)113 TEST(CSSSyntaxParserTest, ParseMultipleProp2) {
114 const wchar_t* input = L"foo:bar;baz:bam;";
115 CFX_CSSSyntaxParser parser(input);
116 parser.SetParseOnlyDeclarations();
117 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kPropertyName, parser.DoSyntaxParse());
118 EXPECT_EQ(L"foo", parser.GetCurrentString());
119 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kPropertyValue,
120 parser.DoSyntaxParse());
121 EXPECT_EQ(L"bar", parser.GetCurrentString());
122 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kPropertyName, parser.DoSyntaxParse());
123 EXPECT_EQ(L"baz", parser.GetCurrentString());
124 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kPropertyValue,
125 parser.DoSyntaxParse());
126 EXPECT_EQ(L"bam", parser.GetCurrentString());
127 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kEOS, parser.DoSyntaxParse());
128 }
129
TEST(CSSSyntaxParserTest,ParseOpenBrace1)130 TEST(CSSSyntaxParserTest, ParseOpenBrace1) {
131 const wchar_t* input = L"{a:3}";
132 CFX_CSSSyntaxParser parser(input);
133 parser.SetParseOnlyDeclarations();
134
135 // TODO(tsepez): these should fail on stray punctuation.
136 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kPropertyName, parser.DoSyntaxParse());
137 EXPECT_EQ(L"{a", parser.GetCurrentString());
138 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kPropertyValue,
139 parser.DoSyntaxParse());
140 EXPECT_EQ(L"3", parser.GetCurrentString());
141 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kError, parser.DoSyntaxParse());
142 }
143
TEST(CSSSyntaxParserTest,ParseOpenBrace2)144 TEST(CSSSyntaxParserTest, ParseOpenBrace2) {
145 const wchar_t* input = L"foo {a:3}";
146 CFX_CSSSyntaxParser parser(input);
147 parser.SetParseOnlyDeclarations();
148
149 // TODO(tsepez): these should fail on stray punctuation.
150 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kPropertyName, parser.DoSyntaxParse());
151 EXPECT_EQ(L"foo {a", parser.GetCurrentString());
152 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kPropertyValue,
153 parser.DoSyntaxParse());
154 EXPECT_EQ(L"3", parser.GetCurrentString());
155 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kError, parser.DoSyntaxParse());
156 }
157
TEST(CSSSyntaxParserTest,ParseOpenBrace3)158 TEST(CSSSyntaxParserTest, ParseOpenBrace3) {
159 const wchar_t* input = L"foo: bar {a:3}";
160 CFX_CSSSyntaxParser parser(input);
161 parser.SetParseOnlyDeclarations();
162
163 // TODO(tsepez): these should fail on stray punctuation.
164 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kPropertyName, parser.DoSyntaxParse());
165 EXPECT_EQ(L"foo", parser.GetCurrentString());
166 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kPropertyValue,
167 parser.DoSyntaxParse());
168 EXPECT_EQ(L"bar {a:3", parser.GetCurrentString());
169 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kError, parser.DoSyntaxParse());
170 }
171
TEST(CSSSyntaxParserTest,ParseOpenBrace4)172 TEST(CSSSyntaxParserTest, ParseOpenBrace4) {
173 const wchar_t* input = L"foo: bar; {a:3}";
174 CFX_CSSSyntaxParser parser(input);
175 parser.SetParseOnlyDeclarations();
176 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kPropertyName, parser.DoSyntaxParse());
177 EXPECT_EQ(L"foo", parser.GetCurrentString());
178 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kPropertyValue,
179 parser.DoSyntaxParse());
180 EXPECT_EQ(L"bar", parser.GetCurrentString());
181
182 // TODO(tsepez): these should fail on stray punctuation.
183 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kPropertyName, parser.DoSyntaxParse());
184 EXPECT_EQ(L"{a", parser.GetCurrentString());
185 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kPropertyValue,
186 parser.DoSyntaxParse());
187 EXPECT_EQ(L"3", parser.GetCurrentString());
188 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kError, parser.DoSyntaxParse());
189 }
190
TEST(CSSSyntaxParserTest,ParseCloseBrace1)191 TEST(CSSSyntaxParserTest, ParseCloseBrace1) {
192 const wchar_t* input = L"} foo:bar";
193 CFX_CSSSyntaxParser parser(input);
194 parser.SetParseOnlyDeclarations();
195 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kError, parser.DoSyntaxParse());
196 }
197
TEST(CSSSyntaxParserTest,ParseCloseBrace2)198 TEST(CSSSyntaxParserTest, ParseCloseBrace2) {
199 const wchar_t* input = L"foo}:bar";
200 CFX_CSSSyntaxParser parser(input);
201 parser.SetParseOnlyDeclarations();
202 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kError, parser.DoSyntaxParse());
203 }
204
TEST(CSSSyntaxParserTest,ParseCloseBrace3)205 TEST(CSSSyntaxParserTest, ParseCloseBrace3) {
206 const wchar_t* input = L"foo:bar}";
207 CFX_CSSSyntaxParser parser(input);
208 parser.SetParseOnlyDeclarations();
209 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kPropertyName, parser.DoSyntaxParse());
210 EXPECT_EQ(L"foo", parser.GetCurrentString());
211 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kPropertyValue,
212 parser.DoSyntaxParse());
213 EXPECT_EQ(L"bar", parser.GetCurrentString());
214 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kError, parser.DoSyntaxParse());
215 }
216
TEST(CSSSyntaxParserTest,ParseCloseBrace4)217 TEST(CSSSyntaxParserTest, ParseCloseBrace4) {
218 const wchar_t* input = L"foo:bar;}";
219 CFX_CSSSyntaxParser parser(input);
220 parser.SetParseOnlyDeclarations();
221 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kPropertyName, parser.DoSyntaxParse());
222 EXPECT_EQ(L"foo", parser.GetCurrentString());
223 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kPropertyValue,
224 parser.DoSyntaxParse());
225 EXPECT_EQ(L"bar", parser.GetCurrentString());
226 EXPECT_EQ(CFX_CSSSyntaxParser::Status::kError, parser.DoSyntaxParse());
227 }
228