| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library declaration_test; | 5 library declaration_test; |
| 6 | 6 |
| 7 import 'package:csslib/src/messages.dart'; |
| 8 import 'package:csslib/visitor.dart'; |
| 7 import 'package:test/test.dart'; | 9 import 'package:test/test.dart'; |
| 8 | 10 |
| 9 import 'testing.dart'; | 11 import 'testing.dart'; |
| 10 | 12 |
| 13 void expectCss(String css, String expected) { |
| 14 var errors = <Message>[]; |
| 15 var styleSheet = parseCss(css, errors: errors, opts: simpleOptions); |
| 16 expect(styleSheet, isNotNull); |
| 17 expect(errors, isEmpty); |
| 18 expect(prettyPrint(styleSheet), expected); |
| 19 } |
| 20 |
| 11 void testSimpleTerms() { | 21 void testSimpleTerms() { |
| 12 var errors = []; | 22 var errors = <Message>[]; |
| 13 final String input = r''' | 23 final String input = r''' |
| 14 @ import url("test.css"); | 24 @ import url("test.css"); |
| 15 .foo { | 25 .foo { |
| 16 background-color: #191919; | 26 background-color: #191919; |
| 27 content: "u+0041"; |
| 17 width: 10PX; | 28 width: 10PX; |
| 18 height: 22mM !important; | 29 height: 22mM !important; |
| 19 border-width: 20cm; | 30 border-width: 20cm; |
| 20 margin-width: 33%; | 31 margin-width: 33%; |
| 21 border-height: 30EM; | 32 border-height: 30EM; |
| 22 width: .6in; | 33 width: .6in; |
| 23 length: 1.2in; | 34 length: 1.2in; |
| 24 -web-stuff: -10Px; | 35 -web-stuff: -10Px; |
| 25 }'''; | 36 }'''; |
| 26 final String generated = r''' | 37 final String generated = r''' |
| 27 @import "test.css"; | 38 @import "test.css"; |
| 28 .foo { | 39 .foo { |
| 29 background-color: #191919; | 40 background-color: #191919; |
| 41 content: "u+0041"; |
| 30 width: 10px; | 42 width: 10px; |
| 31 height: 22mm !important; | 43 height: 22mm !important; |
| 32 border-width: 20cm; | 44 border-width: 20cm; |
| 33 margin-width: 33%; | 45 margin-width: 33%; |
| 34 border-height: 30em; | 46 border-height: 30em; |
| 35 width: .6in; | 47 width: .6in; |
| 36 length: 1.2in; | 48 length: 1.2in; |
| 37 -web-stuff: -10px; | 49 -web-stuff: -10px; |
| 38 }'''; | 50 }'''; |
| 39 | 51 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 50 final String generated2 = r''' | 62 final String generated2 = r''' |
| 51 * { | 63 * { |
| 52 border-color: #008000; | 64 border-color: #008000; |
| 53 }'''; | 65 }'''; |
| 54 | 66 |
| 55 stylesheet = parseCss(input2, errors: errors..clear()); | 67 stylesheet = parseCss(input2, errors: errors..clear()); |
| 56 | 68 |
| 57 expect(stylesheet != null, true); | 69 expect(stylesheet != null, true); |
| 58 expect(errors.isEmpty, true, reason: errors.toString()); | 70 expect(errors.isEmpty, true, reason: errors.toString()); |
| 59 expect(prettyPrint(stylesheet), generated2); | 71 expect(prettyPrint(stylesheet), generated2); |
| 72 |
| 73 // Regression test to ensure invalid percentages don't throw an exception and |
| 74 // instead print a useful error message when not in checked mode. |
| 75 var css = ''' |
| 76 .foo { |
| 77 width: Infinity%; |
| 78 }'''; |
| 79 stylesheet = parseCss(css, errors: errors..clear(), opts: simpleOptions); |
| 80 expect(errors, isNotEmpty); |
| 81 expect(errors.first.message, 'expected }, but found %'); |
| 82 expect(errors.first.span.text, '%'); |
| 60 } | 83 } |
| 61 | 84 |
| 62 /** | 85 /** |
| 63 * Declarations with comments, references with single-quotes, double-quotes, | 86 * Declarations with comments, references with single-quotes, double-quotes, |
| 64 * no quotes. Hex values with # and letters, and functions (rgba, url, etc.) | 87 * no quotes. Hex values with # and letters, and functions (rgba, url, etc.) |
| 65 */ | 88 */ |
| 66 void testDeclarations() { | 89 void testDeclarations() { |
| 67 var errors = []; | 90 var errors = <Message>[]; |
| 68 final String input = r''' | 91 final String input = r''' |
| 69 .more { | 92 .more { |
| 70 color: white; | 93 color: white; |
| 71 color: black; | 94 color: black; |
| 72 color: cyan; | 95 color: cyan; |
| 73 color: red; | 96 color: red; |
| 74 color: #aabbcc; /* test -- 3 */ | 97 color: #aabbcc; /* test -- 3 */ |
| 75 color: blue; | 98 color: blue; |
| 76 background-image: url(http://test.jpeg); | 99 background-image: url(http://test.jpeg); |
| 77 background-image: url("http://double_quote.html"); | 100 background-image: url("http://double_quote.html"); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 95 }'''; | 118 }'''; |
| 96 | 119 |
| 97 var stylesheet = parseCss(input, errors: errors); | 120 var stylesheet = parseCss(input, errors: errors); |
| 98 | 121 |
| 99 expect(stylesheet != null, true); | 122 expect(stylesheet != null, true); |
| 100 expect(errors.isEmpty, true, reason: errors.toString()); | 123 expect(errors.isEmpty, true, reason: errors.toString()); |
| 101 expect(prettyPrint(stylesheet), generated); | 124 expect(prettyPrint(stylesheet), generated); |
| 102 } | 125 } |
| 103 | 126 |
| 104 void testIdentifiers() { | 127 void testIdentifiers() { |
| 105 var errors = []; | 128 var errors = <Message>[]; |
| 106 final String input = r''' | 129 final String input = r''' |
| 107 #da { | 130 #da { |
| 108 height: 100px; | 131 height: 100px; |
| 109 } | 132 } |
| 110 #foo { | 133 #foo { |
| 111 width: 10px; | 134 width: 10px; |
| 112 color: #ff00cc; | 135 color: #ff00cc; |
| 113 } | 136 } |
| 114 '''; | 137 '''; |
| 115 final String generated = r''' | 138 final String generated = r''' |
| 116 #da { | 139 #da { |
| 117 height: 100px; | 140 height: 100px; |
| 118 } | 141 } |
| 119 #foo { | 142 #foo { |
| 120 width: 10px; | 143 width: 10px; |
| 121 color: #f0c; | 144 color: #f0c; |
| 122 }'''; | 145 }'''; |
| 123 | 146 |
| 124 var stylesheet = parseCss(input, errors: errors); | 147 var stylesheet = parseCss(input, errors: errors); |
| 125 | 148 |
| 126 expect(errors.isEmpty, true, reason: errors.toString()); | 149 expect(errors.isEmpty, true, reason: errors.toString()); |
| 127 expect(stylesheet != null, true); | 150 expect(stylesheet != null, true); |
| 128 expect(prettyPrint(stylesheet), generated); | 151 expect(prettyPrint(stylesheet), generated); |
| 129 } | 152 } |
| 130 | 153 |
| 131 void testComposites() { | 154 void testComposites() { |
| 132 var errors = []; | 155 var errors = <Message>[]; |
| 133 final String input = r''' | 156 final String input = r''' |
| 134 .xyzzy { | 157 .xyzzy { |
| 135 border: 10px 80px 90px 100px; | 158 border: 10px 80px 90px 100px; |
| 136 width: 99%; | 159 width: 99%; |
| 137 } | 160 } |
| 138 @-webkit-keyframes pulsate { | 161 @-webkit-keyframes pulsate { |
| 139 0% { | 162 0% { |
| 140 -webkit-transform: translate3d(0, 0, 0) scale(1.0); | 163 -webkit-transform: translate3d(0, 0, 0) scale(1.0); |
| 141 } | 164 } |
| 142 }'''; | 165 }'''; |
| 143 final String generated = r''' | 166 final String generated = r''' |
| 144 .xyzzy { | 167 .xyzzy { |
| 145 border: 10px 80px 90px 100px; | 168 border: 10px 80px 90px 100px; |
| 146 width: 99%; | 169 width: 99%; |
| 147 } | 170 } |
| 148 @-webkit-keyframes pulsate { | 171 @-webkit-keyframes pulsate { |
| 149 0% { | 172 0% { |
| 150 -webkit-transform: translate3d(0, 0, 0) scale(1.0); | 173 -webkit-transform: translate3d(0, 0, 0) scale(1.0); |
| 151 } | 174 } |
| 152 }'''; | 175 }'''; |
| 153 | 176 |
| 154 var stylesheet = parseCss(input, errors: errors); | 177 var stylesheet = parseCss(input, errors: errors); |
| 155 expect(stylesheet != null, true); | 178 expect(stylesheet != null, true); |
| 156 expect(errors.isEmpty, true, reason: errors.toString()); | 179 expect(errors.isEmpty, true, reason: errors.toString()); |
| 157 expect(prettyPrint(stylesheet), generated); | 180 expect(prettyPrint(stylesheet), generated); |
| 158 } | 181 } |
| 159 | 182 |
| 160 void testUnits() { | 183 void testUnits() { |
| 161 var errors = []; | 184 var errors = <Message>[]; |
| 162 final String input = r''' | 185 final String input = r''' |
| 163 #id-1 { | 186 #id-1 { |
| 164 transition: color 0.4s; | 187 transition: color 0.4s; |
| 165 animation-duration: 500ms; | 188 animation-duration: 500ms; |
| 166 top: 1em; | 189 top: 1em; |
| 167 left: 200ex; | 190 left: 200ex; |
| 168 right: 300px; | 191 right: 300px; |
| 169 bottom: 400cm; | 192 bottom: 400cm; |
| 170 border-width: 2.5mm; | 193 border-width: 2.5mm; |
| 171 margin-top: .5in; | 194 margin-top: -.5in; |
| 172 margin-left: 5pc; | 195 margin-left: +5pc; |
| 173 margin-right: 5ex; | 196 margin-right: 5ex; |
| 174 margin-bottom: 5ch; | 197 margin-bottom: 5ch; |
| 175 font-size: 10pt; | 198 font-size: 10pt; |
| 176 padding-top: 22rem; | 199 padding-top: 22rem; |
| 177 padding-left: 33vw; | 200 padding-left: 33vw; |
| 178 padding-right: 34vh; | 201 padding-right: 34vh; |
| 179 padding-bottom: 3vmin; | 202 padding-bottom: 3vmin; |
| 180 transform: rotate(20deg); | 203 transform: rotate(20deg); |
| 181 voice-pitch: 10hz; | 204 voice-pitch: 10hz; |
| 182 } | 205 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 199 | 222 |
| 200 final String generated = r''' | 223 final String generated = r''' |
| 201 #id-1 { | 224 #id-1 { |
| 202 transition: color 0.4s; | 225 transition: color 0.4s; |
| 203 animation-duration: 500ms; | 226 animation-duration: 500ms; |
| 204 top: 1em; | 227 top: 1em; |
| 205 left: 200ex; | 228 left: 200ex; |
| 206 right: 300px; | 229 right: 300px; |
| 207 bottom: 400cm; | 230 bottom: 400cm; |
| 208 border-width: 2.5mm; | 231 border-width: 2.5mm; |
| 209 margin-top: .5in; | 232 margin-top: -.5in; |
| 210 margin-left: 5pc; | 233 margin-left: +5pc; |
| 211 margin-right: 5ex; | 234 margin-right: 5ex; |
| 212 margin-bottom: 5ch; | 235 margin-bottom: 5ch; |
| 213 font-size: 10pt; | 236 font-size: 10pt; |
| 214 padding-top: 22rem; | 237 padding-top: 22rem; |
| 215 padding-left: 33vw; | 238 padding-left: 33vw; |
| 216 padding-right: 34vh; | 239 padding-right: 34vh; |
| 217 padding-bottom: 3vmin; | 240 padding-bottom: 3vmin; |
| 218 transform: rotate(20deg); | 241 transform: rotate(20deg); |
| 219 voice-pitch: 10hz; | 242 voice-pitch: 10hz; |
| 220 } | 243 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 235 }'''; | 258 }'''; |
| 236 | 259 |
| 237 var stylesheet = parseCss(input, errors: errors, opts: simpleOptions); | 260 var stylesheet = parseCss(input, errors: errors, opts: simpleOptions); |
| 238 | 261 |
| 239 expect(stylesheet != null, true); | 262 expect(stylesheet != null, true); |
| 240 expect(errors.isEmpty, true, reason: errors.toString()); | 263 expect(errors.isEmpty, true, reason: errors.toString()); |
| 241 expect(prettyPrint(stylesheet), generated); | 264 expect(prettyPrint(stylesheet), generated); |
| 242 } | 265 } |
| 243 | 266 |
| 244 void testUnicode() { | 267 void testUnicode() { |
| 245 var errors = []; | 268 var errors = <Message>[]; |
| 246 final String input = r''' | 269 final String input = r''' |
| 247 .toggle:after { | 270 .toggle:after { |
| 248 content: '✔'; | 271 content: '✔'; |
| 249 line-height: 43px; | 272 line-height: 43px; |
| 250 font-size: 20px; | 273 font-size: 20px; |
| 251 color: #d9d9d9; | 274 color: #d9d9d9; |
| 252 text-shadow: 0 -1px 0 #bfbfbf; | 275 text-shadow: 0 -1px 0 #bfbfbf; |
| 253 } | 276 } |
| 254 '''; | 277 '''; |
| 255 | 278 |
| 256 final String generated = r''' | 279 final String generated = r''' |
| 257 .toggle:after { | 280 .toggle:after { |
| 258 content: '✔'; | 281 content: '✔'; |
| 259 line-height: 43px; | 282 line-height: 43px; |
| 260 font-size: 20px; | 283 font-size: 20px; |
| 261 color: #d9d9d9; | 284 color: #d9d9d9; |
| 262 text-shadow: 0 -1px 0 #bfbfbf; | 285 text-shadow: 0 -1px 0 #bfbfbf; |
| 263 }'''; | 286 }'''; |
| 264 | 287 |
| 265 var stylesheet = parseCss(input, errors: errors); | 288 var stylesheet = parseCss(input, errors: errors); |
| 266 | 289 |
| 267 expect(stylesheet != null, true); | 290 expect(stylesheet != null, true); |
| 268 expect(errors.isEmpty, true, reason: errors.toString()); | 291 expect(errors.isEmpty, true, reason: errors.toString()); |
| 269 expect(prettyPrint(stylesheet), generated); | 292 expect(prettyPrint(stylesheet), generated); |
| 270 } | 293 } |
| 271 | 294 |
| 272 void testNewerCss() { | 295 void testNewerCss() { |
| 273 var errors = []; | 296 var errors = <Message>[]; |
| 274 final String input = r''' | 297 final String input = r''' |
| 275 @media screen,print { | 298 @media screen,print { |
| 276 .foobar_screen { | 299 .foobar_screen { |
| 277 width: 10px; | 300 width: 10px; |
| 278 } | 301 } |
| 279 } | 302 } |
| 280 @page { | 303 @page { |
| 281 height: 22px; | 304 height: 22px; |
| 282 size: 3in 3in; | 305 size: 3in 3in; |
| 283 } | 306 } |
| 284 @page : left { | 307 @page : left { |
| 285 width: 10px; | 308 width: 10px; |
| 286 } | 309 } |
| 287 @page bar : left { @top-left { margin: 8px; } } | 310 @page bar : left { @top-left { margin: 8px; } } |
| 311 @page { @top-left { margin: 8px; } width: 10px; } |
| 288 @charset "ISO-8859-1"; | 312 @charset "ISO-8859-1"; |
| 289 @charset 'ASCII';'''; | 313 @charset 'ASCII';'''; |
| 290 | 314 |
| 291 final String generated = r''' | 315 final String generated = r''' |
| 292 @media screen, print { | 316 @media screen, print { |
| 293 .foobar_screen { | 317 .foobar_screen { |
| 294 width: 10px; | 318 width: 10px; |
| 295 } | 319 } |
| 296 } | 320 } |
| 297 @page { | 321 @page { |
| 298 height: 22px; | 322 height: 22px; |
| 299 size: 3in 3in; | 323 size: 3in 3in; |
| 300 } | 324 } |
| 301 @page:left { | 325 @page:left { |
| 302 width: 10px; | 326 width: 10px; |
| 303 } | 327 } |
| 304 @page bar:left { | 328 @page bar:left { |
| 305 @top-left { | 329 @top-left { |
| 306 margin: 8px; | 330 margin: 8px; |
| 307 } | 331 } |
| 308 } | 332 } |
| 333 @page { |
| 334 @top-left { |
| 335 margin: 8px; |
| 336 } |
| 337 width: 10px; |
| 338 } |
| 309 @charset "ISO-8859-1"; | 339 @charset "ISO-8859-1"; |
| 310 @charset "ASCII";'''; | 340 @charset "ASCII";'''; |
| 311 | 341 |
| 312 var stylesheet = parseCss(input, errors: errors); | 342 var stylesheet = parseCss(input, errors: errors); |
| 313 | 343 |
| 314 expect(stylesheet != null, true); | 344 expect(stylesheet != null, true); |
| 315 expect(errors.isEmpty, true, reason: errors.toString()); | 345 expect(errors.isEmpty, true, reason: errors.toString()); |
| 316 expect(prettyPrint(stylesheet), generated); | 346 expect(prettyPrint(stylesheet), generated); |
| 317 } | 347 } |
| 318 | 348 |
| 319 void testMediaQueries() { | 349 void testMediaQueries() { |
| 320 var errors = []; | 350 var errors = <Message>[]; |
| 321 String input = ''' | 351 String input = ''' |
| 322 @media screen and (-webkit-min-device-pixel-ratio:0) { | 352 @media screen and (-webkit-min-device-pixel-ratio:0) { |
| 323 .todo-item .toggle { | 353 .todo-item .toggle { |
| 324 background: none; | 354 background: none; |
| 325 } | 355 } |
| 326 #todo-item .toggle { | 356 #todo-item .toggle { |
| 327 height: 40px; | 357 height: 40px; |
| 328 } | 358 } |
| 329 }'''; | 359 }'''; |
| 330 String generated = ''' | 360 String generated = ''' |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 362 } | 392 } |
| 363 }'''; | 393 }'''; |
| 364 generated = | 394 generated = |
| 365 '''@media handheld AND (min-width:20em), screen AND (min-width:20em) { | 395 '''@media handheld AND (min-width:20em), screen AND (min-width:20em) { |
| 366 #id { | 396 #id { |
| 367 color: #f00; | 397 color: #f00; |
| 368 } | 398 } |
| 369 .myclass { | 399 .myclass { |
| 370 height: 20px; | 400 height: 20px; |
| 371 } | 401 } |
| 372 } @media print AND (min-resolution:300dpi) { | 402 } |
| 403 @media print AND (min-resolution:300dpi) { |
| 373 #anotherId { | 404 #anotherId { |
| 374 color: #fff; | 405 color: #fff; |
| 375 } | 406 } |
| 376 } @media print AND (min-resolution:280dpcm) { | 407 } |
| 408 @media print AND (min-resolution:280dpcm) { |
| 377 #finalId { | 409 #finalId { |
| 378 color: #aaa; | 410 color: #aaa; |
| 379 } | 411 } |
| 380 .class2 { | 412 .class2 { |
| 381 border: 20px; | 413 border: 20px; |
| 382 } | 414 } |
| 383 }'''; | 415 }'''; |
| 384 | 416 |
| 385 stylesheet = parseCss(input, errors: errors..clear(), opts: simpleOptions); | 417 stylesheet = parseCss(input, errors: errors..clear(), opts: simpleOptions); |
| 386 | 418 |
| 387 expect(stylesheet != null, true); | 419 expect(stylesheet != null, true); |
| 388 expect(errors.isEmpty, true, reason: errors.toString()); | 420 expect(errors.isEmpty, true, reason: errors.toString()); |
| 389 expect(prettyPrint(stylesheet), generated); | 421 expect(prettyPrint(stylesheet), generated); |
| 390 | 422 |
| 391 input = ''' | 423 input = ''' |
| 392 @media only screen and (min-device-width: 4000px) and | 424 @media only screen and (min-device-width: 4000px) and |
| 393 (min-device-height: 2000px), screen (another: 100px) { | 425 (min-device-height: 2000px), screen AND (another: 100px) { |
| 394 html { | 426 html { |
| 395 font-size: 10em; | 427 font-size: 10em; |
| 396 } | 428 } |
| 397 }'''; | 429 }'''; |
| 398 generated = '@media ONLY screen AND (min-device-width:4000px) ' | 430 generated = '@media ONLY screen AND (min-device-width:4000px) ' |
| 399 'AND (min-device-height:2000px), screen (another:100px) {\n' | 431 'AND (min-device-height:2000px), screen AND (another:100px) {\n' |
| 400 'html {\n font-size: 10em;\n}\n}'; | 432 'html {\n font-size: 10em;\n}\n}'; |
| 401 | 433 |
| 402 stylesheet = parseCss(input, errors: errors..clear(), opts: simpleOptions); | 434 stylesheet = parseCss(input, errors: errors..clear(), opts: simpleOptions); |
| 403 | 435 |
| 404 expect(stylesheet != null, true); | 436 expect(stylesheet != null, true); |
| 405 expect(errors.isEmpty, true, reason: errors.toString()); | 437 expect(errors.isEmpty, true, reason: errors.toString()); |
| 406 expect(prettyPrint(stylesheet), generated); | 438 expect(prettyPrint(stylesheet), generated); |
| 407 | 439 |
| 408 input = ''' | 440 input = ''' |
| 409 @media screen,print (min-device-width: 4000px) and | 441 @media screen,print AND (min-device-width: 4000px) and |
| 410 (min-device-height: 2000px), screen (another: 100px) { | 442 (min-device-height: 2000px), screen AND (another: 100px) { |
| 411 html { | 443 html { |
| 412 font-size: 10em; | 444 font-size: 10em; |
| 413 } | 445 } |
| 414 }'''; | 446 }'''; |
| 415 generated = '@media screen, print (min-device-width:4000px) AND ' | 447 generated = '@media screen, print AND (min-device-width:4000px) AND ' |
| 416 '(min-device-height:2000px), screen (another:100px) {\n' | 448 '(min-device-height:2000px), screen AND (another:100px) {\n' |
| 417 'html {\n font-size: 10em;\n}\n}'; | 449 'html {\n font-size: 10em;\n}\n}'; |
| 418 | 450 |
| 419 stylesheet = parseCss(input, errors: errors..clear(), opts: simpleOptions); | 451 stylesheet = parseCss(input, errors: errors..clear(), opts: simpleOptions); |
| 420 | 452 |
| 421 expect(stylesheet != null, true); | 453 expect(stylesheet != null, true); |
| 422 expect(errors.isEmpty, true, reason: errors.toString()); | 454 expect(errors.isEmpty, true, reason: errors.toString()); |
| 423 expect(prettyPrint(stylesheet), generated); | 455 expect(prettyPrint(stylesheet), generated); |
| 424 | 456 |
| 425 input = ''' | 457 input = ''' |
| 426 @import "test.css" ONLY screen, NOT print (min-device-width: 4000px);'''; | 458 @import "test.css" ONLY screen, NOT print AND (min-device-width: 4000px);'''; |
| 427 generated = | 459 generated = '@import "test.css" ONLY screen, ' |
| 428 '@import "test.css" ONLY screen, NOT print (min-device-width:4000px);'; | 460 'NOT print AND (min-device-width:4000px);'; |
| 429 | 461 |
| 430 stylesheet = parseCss(input, errors: errors..clear(), opts: simpleOptions); | 462 stylesheet = parseCss(input, errors: errors..clear(), opts: simpleOptions); |
| 431 | 463 |
| 432 expect(stylesheet != null, true); | 464 expect(stylesheet != null, true); |
| 433 expect(errors.isEmpty, true, reason: errors.toString()); | 465 expect(errors.isEmpty, true, reason: errors.toString()); |
| 434 expect(prettyPrint(stylesheet), generated); | 466 expect(prettyPrint(stylesheet), generated); |
| 467 |
| 468 var css = '@media (min-device-width:400px) {\n}'; |
| 469 expectCss(css, css); |
| 470 |
| 471 css = '@media all AND (tranform-3d), (-webkit-transform-3d) {\n}'; |
| 472 expectCss(css, css); |
| 473 |
| 474 // Test that AND operator is required between media type and expressions. |
| 475 css = '@media screen (min-device-width:400px'; |
| 476 stylesheet = parseCss(css, errors: errors..clear(), opts: simpleOptions); |
| 477 expect(errors, isNotEmpty); |
| 478 expect( |
| 479 errors.first.message, contains('expected { after media before ruleset')); |
| 480 expect(errors.first.span.text, '('); |
| 481 } |
| 482 |
| 483 void testMozDocument() { |
| 484 var errors = <Message>[]; |
| 485 // Test empty url-prefix, commonly used for browser detection. |
| 486 var css = ''' |
| 487 @-moz-document url-prefix() { |
| 488 div { |
| 489 color: #000; |
| 490 } |
| 491 }'''; |
| 492 var expected = '''@-moz-document url-prefix() { |
| 493 div { |
| 494 color: #000; |
| 495 } |
| 496 }'''; |
| 497 var styleSheet = parseCss(css, errors: errors); |
| 498 expect(styleSheet, isNotNull); |
| 499 expect(errors, isEmpty); |
| 500 expect(prettyPrint(styleSheet), expected); |
| 501 |
| 502 // Test url-prefix with unquoted parameter |
| 503 css = ''' |
| 504 @-moz-document url-prefix(http://www.w3.org/Style/) { |
| 505 div { |
| 506 color: #000; |
| 507 } |
| 508 }'''; |
| 509 expected = '''@-moz-document url-prefix("http://www.w3.org/Style/") { |
| 510 div { |
| 511 color: #000; |
| 512 } |
| 513 }'''; |
| 514 styleSheet = parseCss(css, errors: errors); |
| 515 expect(styleSheet, isNotNull); |
| 516 expect(errors, isEmpty); |
| 517 expect(prettyPrint(styleSheet), expected); |
| 518 |
| 519 // Test domain with unquoted parameter |
| 520 css = ''' |
| 521 @-moz-document domain(google.com) { |
| 522 div { |
| 523 color: #000; |
| 524 } |
| 525 }'''; |
| 526 expected = '''@-moz-document domain("google.com") { |
| 527 div { |
| 528 color: #000; |
| 529 } |
| 530 }'''; |
| 531 styleSheet = parseCss(css, errors: errors); |
| 532 expect(styleSheet, isNotNull); |
| 533 expect(errors, isEmpty); |
| 534 expect(prettyPrint(styleSheet), expected); |
| 535 |
| 536 // Test all document functions combined. |
| 537 css = '@-moz-document ' + |
| 538 'url(http://www.w3.org/), ' + |
| 539 "url-prefix('http://www.w3.org/Style/'), " + |
| 540 'domain("google.com"), ' + |
| 541 'regexp("https:.*") { div { color: #000; } }'; |
| 542 expected = '@-moz-document ' + |
| 543 'url("http://www.w3.org/"), ' + |
| 544 'url-prefix("http://www.w3.org/Style/"), ' + |
| 545 'domain("google.com"), ' + |
| 546 'regexp("https:.*") {\ndiv {\n color: #000;\n}\n}'; |
| 547 styleSheet = parseCss(css, errors: errors); |
| 548 expect(styleSheet, isNotNull); |
| 549 expect(errors, isEmpty); |
| 550 expect(prettyPrint(styleSheet), expected); |
| 551 } |
| 552 |
| 553 void testSupports() { |
| 554 // Test single declaration condition. |
| 555 var css = ''' |
| 556 @supports (-webkit-appearance: none) { |
| 557 div { |
| 558 -webkit-appearance: none; |
| 559 } |
| 560 }'''; |
| 561 var expected = '''@supports (-webkit-appearance: none) { |
| 562 div { |
| 563 -webkit-appearance: none; |
| 564 } |
| 565 }'''; |
| 566 expectCss(css, expected); |
| 567 |
| 568 // Test negation. |
| 569 css = ''' |
| 570 @supports not ( display: flex ) { |
| 571 body { width: 100%; } |
| 572 }'''; |
| 573 expected = '''@supports not (display: flex) { |
| 574 body { |
| 575 width: 100%; |
| 576 } |
| 577 }'''; |
| 578 expectCss(css, expected); |
| 579 |
| 580 // Test clause with multiple conditions. |
| 581 css = ''' |
| 582 @supports (box-shadow: 0 0 2px black inset) or |
| 583 (-moz-box-shadow: 0 0 2px black inset) or |
| 584 (-webkit-box-shadow: 0 0 2px black inset) or |
| 585 (-o-box-shadow: 0 0 2px black inset) { |
| 586 .box { |
| 587 box-shadow: 0 0 2px black inset; |
| 588 } |
| 589 }'''; |
| 590 expected = '@supports (box-shadow: 0 0 2px #000 inset) or ' + |
| 591 '(-moz-box-shadow: 0 0 2px #000 inset) or ' + |
| 592 '(-webkit-box-shadow: 0 0 2px #000 inset) or ' + |
| 593 '(-o-box-shadow: 0 0 2px #000 inset) {\n' + |
| 594 '.box {\n' + |
| 595 ' box-shadow: 0 0 2px #000 inset;\n' + |
| 596 '}\n' + |
| 597 '}'; |
| 598 expectCss(css, expected); |
| 599 |
| 600 // Test conjunction and disjunction together. |
| 601 css = ''' |
| 602 @supports ((transition-property: color) or (animation-name: foo)) and |
| 603 (transform: rotate(10deg)) { |
| 604 div { |
| 605 transition-property: color; |
| 606 transform: rotate(10deg); |
| 607 } |
| 608 }'''; |
| 609 |
| 610 expected = '@supports ' + |
| 611 '((transition-property: color) or (animation-name: foo)) and ' + |
| 612 '(transform: rotate(10deg)) {\n' + |
| 613 'div {\n' + |
| 614 ' transition-property: color;\n' + |
| 615 ' transform: rotate(10deg);\n' + |
| 616 '}\n' + |
| 617 '}'; |
| 618 expectCss(css, expected); |
| 619 |
| 620 // Test that operators can't be mixed without parentheses. |
| 621 css = '@supports (a: 1) and (b: 2) or (c: 3) {}'; |
| 622 var errors = <Message>[]; |
| 623 var styleSheet = parseCss(css, errors: errors, opts: simpleOptions); |
| 624 expect(styleSheet, isNotNull); |
| 625 expect(errors, isNotEmpty); |
| 626 expect(errors.first.message, |
| 627 "Operators can't be mixed without a layer of parentheses"); |
| 628 expect(errors.first.span.text, 'or'); |
| 629 } |
| 630 |
| 631 void testViewport() { |
| 632 // No declarations. |
| 633 var css = '@viewport {\n}'; |
| 634 expectCss(css, css); |
| 635 |
| 636 // All declarations. |
| 637 css = ''' |
| 638 @viewport { |
| 639 min-width: auto; |
| 640 max-width: 800px; |
| 641 width: 400px; |
| 642 min-height: 50%; |
| 643 max-height: 200px; |
| 644 height: 100px 200px; |
| 645 zoom: auto; |
| 646 min-zoom: 0.75; |
| 647 max-zoom: 40%; |
| 648 user-zoom: fixed; |
| 649 orientation: landscape; |
| 650 }'''; |
| 651 expectCss(css, css); |
| 652 |
| 653 // Vendor specific. |
| 654 css = ''' |
| 655 @-ms-viewport { |
| 656 width: device-width; |
| 657 }'''; |
| 658 expectCss(css, css); |
| 435 } | 659 } |
| 436 | 660 |
| 437 void testFontFace() { | 661 void testFontFace() { |
| 438 var errors = []; | 662 var errors = <Message>[]; |
| 439 | 663 |
| 440 final String input = ''' | 664 final String input = ''' |
| 441 @font-face { | 665 @font-face { |
| 442 font-family: BBCBengali; | 666 font-family: BBCBengali; |
| 443 src: url(fonts/BBCBengali.ttf) format("opentype"); | 667 src: url(fonts/BBCBengali.ttf) format("opentype"); |
| 444 unicode-range: U+0A-FF, U+980-9FF, U+????, U+3???; | 668 unicode-range: U+0A-FF, U+980-9FF, U+????, U+3???; |
| 445 }'''; | 669 }'''; |
| 446 final String generated = '''@font-face { | 670 final String generated = '''@font-face { |
| 447 font-family: BBCBengali; | 671 font-family: BBCBengali; |
| 448 src: url("fonts/BBCBengali.ttf") format("opentype"); | 672 src: url("fonts/BBCBengali.ttf") format("opentype"); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 520 unicode-range: U+000-49F, U+2000-27FF, U+2900-2BFF, U+1D400-1D7FF; | 744 unicode-range: U+000-49F, U+2000-27FF, U+2900-2BFF, U+1D400-1D7FF; |
| 521 }'''; | 745 }'''; |
| 522 stylesheet = parseCss(input4, errors: errors..clear(), opts: simpleOptions); | 746 stylesheet = parseCss(input4, errors: errors..clear(), opts: simpleOptions); |
| 523 | 747 |
| 524 expect(stylesheet != null, true); | 748 expect(stylesheet != null, true); |
| 525 expect(errors.isEmpty, true, reason: errors.toString()); | 749 expect(errors.isEmpty, true, reason: errors.toString()); |
| 526 expect(prettyPrint(stylesheet), generated4); | 750 expect(prettyPrint(stylesheet), generated4); |
| 527 } | 751 } |
| 528 | 752 |
| 529 void testCssFile() { | 753 void testCssFile() { |
| 530 var errors = []; | 754 var errors = <Message>[]; |
| 531 final String input = r''' | 755 final String input = r''' |
| 532 @import 'simple.css' | 756 @import 'simple.css' |
| 533 @import "test.css" print | 757 @import "test.css" print |
| 534 @import url(test.css) screen, print | 758 @import url(test.css) screen, print |
| 535 @import url(http://google.com/maps/maps.css); | 759 @import url(http://google.com/maps/maps.css); |
| 536 | 760 |
| 537 div[href^='test'] { | 761 div[href^='test'] { |
| 538 height: 10px; | 762 height: 10px; |
| 539 } | 763 } |
| 540 | 764 |
| 541 @-webkit-keyframes pulsate { | 765 @-webkit-keyframes pulsate { |
| 542 from { | 766 from { |
| 543 -webkit-transform: translate3d(0, 0, 0) scale(1.0); | 767 -webkit-transform: translate3d(0, 0, 0) scale(1.0); |
| 544 } | 768 } |
| 545 10% { | 769 10% { |
| 546 -webkit-transform: translate3d(0, 0, 0) scale(1.0); | 770 -webkit-transform: translate3d(0, 0, 0) scale(1.0); |
| 547 } | 771 } |
| 548 30% { | 772 30% { |
| 549 -webkit-transform: translate3d(0, 2, 0) scale(1.0); | 773 -webkit-transform: translate3d(0, 2, 0) scale(1.0); |
| 550 } | 774 } |
| 551 } | 775 } |
| 552 | 776 |
| 553 .foobar { | 777 .foobar { |
| 554 grid-columns: 10px ("content" 1fr 10px)[4]; | 778 grid-columns: 10px ("content" 1fr 10px)[4]; |
| 555 } | 779 } |
| 556 | 780 |
| 557 .test-background { | 781 .test-background { |
| 558 background: url(http://www.foo.com/bar.png); | 782 background: url(http://www.foo.com/bar.png); |
| 559 } | 783 } |
| 784 |
| 785 .test-background-with-multiple-properties { |
| 786 background: #000 url(http://www.foo.com/bar.png); |
| 787 } |
| 560 '''; | 788 '''; |
| 561 | 789 |
| 562 final String generated = '@import "simple.css"; ' | 790 final String generated = '@import "simple.css"; ' |
| 563 '@import "test.css" print; ' | 791 '@import "test.css" print; ' |
| 564 '@import "test.css" screen, print; ' | 792 '@import "test.css" screen, print; ' |
| 565 '@import "http://google.com/maps/maps.css";\n' | 793 '@import "http://google.com/maps/maps.css";\n' |
| 566 'div[href^="test"] {\n' | 794 'div[href^="test"] {\n' |
| 567 ' height: 10px;\n' | 795 ' height: 10px;\n' |
| 568 '}\n' | 796 '}\n' |
| 569 '@-webkit-keyframes pulsate {\n' | 797 '@-webkit-keyframes pulsate {\n' |
| 570 ' from {\n' | 798 ' from {\n' |
| 571 ' -webkit-transform: translate3d(0, 0, 0) scale(1.0);\n' | 799 ' -webkit-transform: translate3d(0, 0, 0) scale(1.0);\n' |
| 572 ' }\n' | 800 ' }\n' |
| 573 ' 10% {\n' | 801 ' 10% {\n' |
| 574 ' -webkit-transform: translate3d(0, 0, 0) scale(1.0);\n' | 802 ' -webkit-transform: translate3d(0, 0, 0) scale(1.0);\n' |
| 575 ' }\n' | 803 ' }\n' |
| 576 ' 30% {\n' | 804 ' 30% {\n' |
| 577 ' -webkit-transform: translate3d(0, 2, 0) scale(1.0);\n' | 805 ' -webkit-transform: translate3d(0, 2, 0) scale(1.0);\n' |
| 578 ' }\n' | 806 ' }\n' |
| 579 '}\n' | 807 '}\n' |
| 580 '.foobar {\n' | 808 '.foobar {\n' |
| 581 ' grid-columns: 10px ("content" 1fr 10px) [4];\n' | 809 ' grid-columns: 10px ("content" 1fr 10px) [4];\n' |
| 582 '}\n' | 810 '}\n' |
| 583 '.test-background {\n' | 811 '.test-background {\n' |
| 584 ' background: url("http://www.foo.com/bar.png");\n' | 812 ' background: url("http://www.foo.com/bar.png");\n' |
| 813 '}\n' |
| 814 '.test-background-with-multiple-properties {\n' |
| 815 ' background: #000 url("http://www.foo.com/bar.png");\n' |
| 585 '}'; | 816 '}'; |
| 586 var stylesheet = parseCss(input, errors: errors); | 817 var stylesheet = parseCss(input, errors: errors); |
| 587 | 818 |
| 588 expect(stylesheet != null, true); | 819 expect(stylesheet != null, true); |
| 589 expect(errors.isEmpty, true, reason: errors.toString()); | 820 expect(errors.isEmpty, true, reason: errors.toString()); |
| 590 expect(prettyPrint(stylesheet), generated); | 821 expect(prettyPrint(stylesheet), generated); |
| 591 } | 822 } |
| 592 | 823 |
| 593 void testCompactEmitter() { | 824 void testCompactEmitter() { |
| 594 var errors = []; | 825 var errors = <Message>[]; |
| 595 | 826 |
| 596 // Check !import compactly emitted. | 827 // Check !import compactly emitted. |
| 597 final String input = r''' | 828 final String input = r''' |
| 598 div { | 829 div { |
| 599 color: green !important; | 830 color: green !important; |
| 600 } | 831 } |
| 601 '''; | 832 '''; |
| 602 final String generated = "div { color: green!important; }"; | 833 final String generated = "div { color:green!important; }"; |
| 603 | 834 |
| 604 var stylesheet = parseCss(input, errors: errors); | 835 var stylesheet = parseCss(input, errors: errors); |
| 605 | 836 |
| 606 expect(stylesheet != null, true); | 837 expect(stylesheet != null, true); |
| 607 expect(errors.isEmpty, true, reason: errors.toString()); | 838 expect(errors.isEmpty, true, reason: errors.toString()); |
| 608 expect(compactOuptut(stylesheet), generated); | 839 expect(compactOuptut(stylesheet), generated); |
| 609 | 840 |
| 610 // Check namespace directive compactly emitted. | 841 // Check namespace directive compactly emitted. |
| 611 final String input2 = "@namespace a url(http://www.example.org/a);"; | 842 final String input2 = "@namespace a url(http://www.example.org/a);"; |
| 612 final String generated2 = "@namespace a url(http://www.example.org/a);"; | 843 final String generated2 = "@namespace a url(http://www.example.org/a);"; |
| 613 | 844 |
| 614 var stylesheet2 = parseCss(input2, errors: errors..clear()); | 845 var stylesheet2 = parseCss(input2, errors: errors..clear()); |
| 615 | 846 |
| 616 expect(stylesheet2 != null, true); | 847 expect(stylesheet2 != null, true); |
| 617 expect(errors.isEmpty, true, reason: errors.toString()); | 848 expect(errors.isEmpty, true, reason: errors.toString()); |
| 618 expect(compactOuptut(stylesheet2), generated2); | 849 expect(compactOuptut(stylesheet2), generated2); |
| 619 } | 850 } |
| 620 | 851 |
| 621 void testNotSelectors() { | 852 void testNotSelectors() { |
| 622 var errors = []; | 853 var errors = <Message>[]; |
| 623 | 854 |
| 624 final String input = r''' | 855 final String input = r''' |
| 625 .details:not(.open-details) x-element, | 856 .details:not(.open-details) x-element, |
| 626 .details:not(.open-details) .summary { | 857 .details:not(.open-details) .summary { |
| 627 overflow: hidden; | 858 overflow: hidden; |
| 628 } | 859 } |
| 629 | 860 |
| 630 .details:not(.open-details) x-icon { | 861 .details:not(.open-details) x-icon { |
| 631 margin-left: 99px; | 862 margin-left: 99px; |
| 632 } | 863 } |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 702 }'''; | 933 }'''; |
| 703 | 934 |
| 704 var stylesheet = parseCss(input, errors: errors, opts: simpleOptions); | 935 var stylesheet = parseCss(input, errors: errors, opts: simpleOptions); |
| 705 | 936 |
| 706 expect(stylesheet != null, true); | 937 expect(stylesheet != null, true); |
| 707 expect(errors.isEmpty, true, reason: errors.toString()); | 938 expect(errors.isEmpty, true, reason: errors.toString()); |
| 708 expect(prettyPrint(stylesheet), generated); | 939 expect(prettyPrint(stylesheet), generated); |
| 709 } | 940 } |
| 710 | 941 |
| 711 void testIE() { | 942 void testIE() { |
| 712 var errors = []; | 943 var errors = <Message>[]; |
| 713 final String input = ".test {\n" | 944 final String input = ".test {\n" |
| 714 " filter: progid:DXImageTransform.Microsoft.gradient" | 945 " filter: progid:DXImageTransform.Microsoft.gradient" |
| 715 "(GradientType=0,StartColorStr='#9d8b83', EndColorStr='#847670');\n" | 946 "(GradientType=0,StartColorStr='#9d8b83', EndColorStr='#847670');\n" |
| 716 "}"; | 947 "}"; |
| 717 final String generated = ".test {\n" | 948 final String generated = ".test {\n" |
| 718 " filter: progid:DXImageTransform.Microsoft.gradient" | 949 " filter: progid:DXImageTransform.Microsoft.gradient" |
| 719 "(GradientType=0,StartColorStr='#9d8b83', EndColorStr='#847670');\n" | 950 "(GradientType=0,StartColorStr='#9d8b83', EndColorStr='#847670');\n" |
| 720 "}"; | 951 "}"; |
| 721 | 952 |
| 722 var stylesheet = parseCss(input, errors: errors, opts: simpleOptions); | 953 var stylesheet = parseCss(input, errors: errors, opts: simpleOptions); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 765 ' Filter: Alpha(Opacity=100, FinishOpacity=0, Style=2, ' | 996 ' Filter: Alpha(Opacity=100, FinishOpacity=0, Style=2, ' |
| 766 'StartX=20, StartY=40,\n' | 997 'StartX=20, StartY=40,\n' |
| 767 ' FinishX=0, FinishY=0) Wave(Add=0, Freq=5, LightStrength=20,\n' | 998 ' FinishX=0, FinishY=0) Wave(Add=0, Freq=5, LightStrength=20,\n' |
| 768 ' Phase=220, Strength=10);\n}'; | 999 ' Phase=220, Strength=10);\n}'; |
| 769 | 1000 |
| 770 stylesheet = parseCss(input3, errors: errors..clear(), opts: simpleOptions); | 1001 stylesheet = parseCss(input3, errors: errors..clear(), opts: simpleOptions); |
| 771 | 1002 |
| 772 expect(stylesheet != null, true); | 1003 expect(stylesheet != null, true); |
| 773 expect(errors.isEmpty, true, reason: errors.toString()); | 1004 expect(errors.isEmpty, true, reason: errors.toString()); |
| 774 expect(prettyPrint(stylesheet), generated3); | 1005 expect(prettyPrint(stylesheet), generated3); |
| 1006 |
| 1007 final input4 = ''' |
| 1008 div { |
| 1009 filter: FlipH; |
| 1010 }'''; |
| 1011 |
| 1012 stylesheet = parseCss(input4, errors: errors..clear(), opts: simpleOptions); |
| 1013 |
| 1014 expect(stylesheet != null, true); |
| 1015 expect(errors.isEmpty, true, reason: errors.toString()); |
| 1016 expect(prettyPrint(stylesheet), input4); |
| 775 } | 1017 } |
| 776 | 1018 |
| 777 /** | 1019 /** |
| 778 * Test IE specific declaration syntax: | 1020 * Test IE specific declaration syntax: |
| 779 * IE6 property name prefixed with _ (normal CSS property name can start | 1021 * IE6 property name prefixed with _ (normal CSS property name can start |
| 780 * with an underscore). | 1022 * with an underscore). |
| 781 * | 1023 * |
| 782 * IE7 or below property add asterisk before the CSS property. | 1024 * IE7 or below property add asterisk before the CSS property. |
| 783 * | 1025 * |
| 784 * IE8 or below add \9 at end of declaration expression e.g., | 1026 * IE8 or below add \9 at end of declaration expression e.g., |
| 785 * background: red\9; | 1027 * background: red\9; |
| 786 */ | 1028 */ |
| 787 void testIEDeclaration() { | 1029 void testIEDeclaration() { |
| 788 var errors = []; | 1030 var errors = <Message>[]; |
| 789 | 1031 |
| 790 final input = ''' | 1032 final input = ''' |
| 791 .testIE-6 { | 1033 .testIE-6 { |
| 792 _zoom : 5; | 1034 _zoom : 5; |
| 793 } | 1035 } |
| 794 .clearfix { | 1036 .clearfix { |
| 795 *zoom: 1; | 1037 *zoom: 1; |
| 796 } | 1038 } |
| 797 audio, video { | 1039 audio, video { |
| 798 display: inline-block; | 1040 display: inline-block; |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 944 } | 1186 } |
| 945 }'''; | 1187 }'''; |
| 946 | 1188 |
| 947 var stylesheet = parseCss(input, errors: errors, opts: simpleOptions); | 1189 var stylesheet = parseCss(input, errors: errors, opts: simpleOptions); |
| 948 expect(stylesheet != null, true); | 1190 expect(stylesheet != null, true); |
| 949 expect(errors.isEmpty, true, reason: errors.toString()); | 1191 expect(errors.isEmpty, true, reason: errors.toString()); |
| 950 expect(prettyPrint(stylesheet), generated); | 1192 expect(prettyPrint(stylesheet), generated); |
| 951 } | 1193 } |
| 952 | 1194 |
| 953 void testHangs() { | 1195 void testHangs() { |
| 954 var errors = []; | 1196 var errors = <Message>[]; |
| 955 | 1197 |
| 956 // Bad hexvalue had caused a hang in processTerm. | 1198 // Bad hexvalue had caused a hang in processTerm. |
| 957 final input = r'''#a { color: #ebebeburl(0/IE8+9+); }'''; | 1199 final input = r'''#a { color: #ebebeburl(0/IE8+9+); }'''; |
| 958 var stylesheet = parseCss(input, errors: errors, opts: options); | 1200 var stylesheet = parseCss(input, errors: errors, opts: options); |
| 959 | 1201 |
| 960 expect(stylesheet != null, true); | 1202 expect(stylesheet != null, true); |
| 961 expect(errors.length, 3, reason: errors.toString()); | 1203 expect(errors.length, 3, reason: errors.toString()); |
| 962 | 1204 |
| 963 var errorMessage = errors[0]; | 1205 var errorMessage = errors[0]; |
| 964 expect(errorMessage.message, contains('Bad hex number')); | 1206 expect(errorMessage.message, contains('Bad hex number')); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1001 expect(errorMessage.message, contains('unexpected end of file')); | 1243 expect(errorMessage.message, contains('unexpected end of file')); |
| 1002 expect(errorMessage.span, isNotNull); | 1244 expect(errorMessage.span, isNotNull); |
| 1003 expect(errorMessage.span.start.line, 7); | 1245 expect(errorMessage.span.start.line, 7); |
| 1004 expect(errorMessage.span.start.column, 0); | 1246 expect(errorMessage.span.start.column, 0); |
| 1005 expect(errorMessage.span.text.trim(), ''); | 1247 expect(errorMessage.span.text.trim(), ''); |
| 1006 } | 1248 } |
| 1007 | 1249 |
| 1008 void testExpressionSpans() { | 1250 void testExpressionSpans() { |
| 1009 final input = r'''.foo { width: 50px; }'''; | 1251 final input = r'''.foo { width: 50px; }'''; |
| 1010 var stylesheet = parseCss(input); | 1252 var stylesheet = parseCss(input); |
| 1011 var decl = stylesheet.topLevels.single.declarationGroup.declarations.single; | 1253 var decl = (stylesheet.topLevels.single as RuleSet) |
| 1254 .declarationGroup |
| 1255 .declarations |
| 1256 .single; |
| 1012 // This passes | 1257 // This passes |
| 1013 expect(decl.span.text, 'width: 50px'); | 1258 expect(decl.span.text, 'width: 50px'); |
| 1014 // This currently fails | 1259 // This currently fails |
| 1015 expect(decl.expression.span.text, '50px'); | 1260 expect((decl as Declaration).expression.span.text, '50px'); |
| 1016 } | 1261 } |
| 1017 | 1262 |
| 1018 void simpleCalc() { | 1263 void simpleCalc() { |
| 1019 final input = r'''.foo { height: calc(100% - 55px); }'''; | 1264 final input = r'''.foo { height: calc(100% - 55px); }'''; |
| 1020 var stylesheet = parseCss(input); | 1265 var stylesheet = parseCss(input); |
| 1021 var decl = stylesheet.topLevels.single.declarationGroup.declarations.single; | 1266 var decl = (stylesheet.topLevels.single as RuleSet) |
| 1267 .declarationGroup |
| 1268 .declarations |
| 1269 .single; |
| 1022 expect(decl.span.text, 'height: calc(100% - 55px)'); | 1270 expect(decl.span.text, 'height: calc(100% - 55px)'); |
| 1023 } | 1271 } |
| 1024 | 1272 |
| 1025 void complexCalc() { | 1273 void complexCalc() { |
| 1026 final input = r'''.foo { left: calc((100%/3 - 2) * 1em - 2 * 1px); }'''; | 1274 final input = r'''.foo { left: calc((100%/3 - 2) * 1em - 2 * 1px); }'''; |
| 1027 var stylesheet = parseCss(input); | 1275 var stylesheet = parseCss(input); |
| 1028 var decl = stylesheet.topLevels.single.declarationGroup.declarations.single; | 1276 var decl = (stylesheet.topLevels.single as RuleSet) |
| 1277 .declarationGroup |
| 1278 .declarations |
| 1279 .single; |
| 1029 expect(decl.span.text, 'left: calc((100%/3 - 2) * 1em - 2 * 1px)'); | 1280 expect(decl.span.text, 'left: calc((100%/3 - 2) * 1em - 2 * 1px)'); |
| 1030 } | 1281 } |
| 1031 | 1282 |
| 1032 void twoCalcs() { | 1283 void twoCalcs() { |
| 1033 final input = r'''.foo { margin: calc(1rem - 2px) calc(1rem - 1px); }'''; | 1284 final input = r'''.foo { margin: calc(1rem - 2px) calc(1rem - 1px); }'''; |
| 1034 var stylesheet = parseCss(input); | 1285 var stylesheet = parseCss(input); |
| 1035 var decl = stylesheet.topLevels.single.declarationGroup.declarations.single; | 1286 var decl = (stylesheet.topLevels.single as RuleSet) |
| 1287 .declarationGroup |
| 1288 .declarations |
| 1289 .single; |
| 1036 expect(decl.span.text, 'margin: calc(1rem - 2px) calc(1rem - 1px)'); | 1290 expect(decl.span.text, 'margin: calc(1rem - 2px) calc(1rem - 1px)'); |
| 1037 } | 1291 } |
| 1038 | 1292 |
| 1039 void selectorWithCalcs() { | 1293 void selectorWithCalcs() { |
| 1040 var errors = []; | 1294 var errors = <Message>[]; |
| 1041 final String input = r''' | 1295 final String input = r''' |
| 1042 .foo { | 1296 .foo { |
| 1043 width: calc(1em + 5 * 2em); | 1297 width: calc(1em + 5 * 2em); |
| 1044 height: calc(1px + 2%) !important; | 1298 height: calc(1px + 2%) !important; |
| 1045 border: 5px calc(1pt + 2cm) 6px calc(1em + 1in + 2px) red; | 1299 border: 5px calc(1pt + 2cm) 6px calc(1em + 1in + 2px) red; |
| 1046 border: calc(5px + 1em) 0px 1px calc(10 + 20 + 1px); | 1300 border: calc(5px + 1em) 0px 1px calc(10 + 20 + 1px); |
| 1047 margin: 25px calc(50px + (100% / (3 - 1em) - 20%)) calc(10px + 10 * 20) calc(1
00% - 10px); | 1301 margin: 25px calc(50px + (100% / (3 - 1em) - 20%)) calc(10px + 10 * 20) calc(1
00% - 10px); |
| 1048 }'''; | 1302 }'''; |
| 1049 final String generated = r''' | 1303 final String generated = r''' |
| 1050 .foo { | 1304 .foo { |
| 1051 width: calc(1em + 5 * 2em); | 1305 width: calc(1em + 5 * 2em); |
| 1052 height: calc(1px + 2%) !important; | 1306 height: calc(1px + 2%) !important; |
| 1053 border: 5px calc(1pt + 2cm) 6px calc(1em + 1in + 2px) #f00; | 1307 border: 5px calc(1pt + 2cm) 6px calc(1em + 1in + 2px) #f00; |
| 1054 border: calc(5px + 1em) 0px 1px calc(10 + 20 + 1px); | 1308 border: calc(5px + 1em) 0px 1px calc(10 + 20 + 1px); |
| 1055 margin: 25px calc(50px + (100% / (3 - 1em) - 20%)) calc(10px + 10 * 20) calc(1
00% - 10px); | 1309 margin: 25px calc(50px + (100% / (3 - 1em) - 20%)) calc(10px + 10 * 20) calc(1
00% - 10px); |
| 1056 }'''; | 1310 }'''; |
| 1057 | 1311 |
| 1058 var stylesheet = parseCss(input, errors: errors); | 1312 var stylesheet = parseCss(input, errors: errors); |
| 1059 expect(stylesheet != null, true); | 1313 expect(stylesheet != null, true); |
| 1060 expect(errors.isEmpty, true, reason: errors.toString()); | 1314 expect(errors.isEmpty, true, reason: errors.toString()); |
| 1061 expect(prettyPrint(stylesheet), generated); | 1315 expect(prettyPrint(stylesheet), generated); |
| 1062 } | 1316 } |
| 1063 | 1317 |
| 1318 void vendorPrefixedCalc() { |
| 1319 var css = ''' |
| 1320 .foo { |
| 1321 width: -webkit-calc((100% - 15px*1) / 1); |
| 1322 }'''; |
| 1323 expectCss(css, css); |
| 1324 |
| 1325 css = ''' |
| 1326 .foo { |
| 1327 width: -moz-calc((100% - 15px*1) / 1); |
| 1328 }'''; |
| 1329 expectCss(css, css); |
| 1330 } |
| 1331 |
| 1064 main() { | 1332 main() { |
| 1065 test('Simple Terms', testSimpleTerms); | 1333 test('Simple Terms', testSimpleTerms); |
| 1066 test('Declarations', testDeclarations); | 1334 test('Declarations', testDeclarations); |
| 1067 test('Identifiers', testIdentifiers); | 1335 test('Identifiers', testIdentifiers); |
| 1068 test('Composites', testComposites); | 1336 test('Composites', testComposites); |
| 1069 test('Units', testUnits); | 1337 test('Units', testUnits); |
| 1070 test('Unicode', testUnicode); | 1338 test('Unicode', testUnicode); |
| 1071 test('Newer CSS', testNewerCss); | 1339 test('Newer CSS', testNewerCss); |
| 1072 test('Media Queries', testMediaQueries); | 1340 test('Media Queries', testMediaQueries); |
| 1341 test('Document', testMozDocument); |
| 1342 test('Supports', testSupports); |
| 1343 test('Viewport', testViewport); |
| 1073 test('Font-Face', testFontFace); | 1344 test('Font-Face', testFontFace); |
| 1074 test('CSS file', testCssFile); | 1345 test('CSS file', testCssFile); |
| 1075 test('Compact Emitter', testCompactEmitter); | 1346 test('Compact Emitter', testCompactEmitter); |
| 1076 test('Selector Negation', testNotSelectors); | 1347 test('Selector Negation', testNotSelectors); |
| 1077 test('IE stuff', testIE); | 1348 test('IE stuff', testIE); |
| 1078 test('IE declaration syntax', testIEDeclaration); | 1349 test('IE declaration syntax', testIEDeclaration); |
| 1079 test('Hanging bugs', testHangs); | 1350 test('Hanging bugs', testHangs); |
| 1080 test('Expression spans', testExpressionSpans, | 1351 test('Expression spans', testExpressionSpans, |
| 1081 skip: 'expression spans are broken' | 1352 skip: 'expression spans are broken' |
| 1082 ' (https://github.com/dart-lang/csslib/issues/15)'); | 1353 ' (https://github.com/dart-lang/csslib/issues/15)'); |
| 1083 group('calc function', () { | 1354 group('calc function', () { |
| 1084 test('simple calc', simpleCalc); | 1355 test('simple calc', simpleCalc); |
| 1085 test('single complex', complexCalc); | 1356 test('single complex', complexCalc); |
| 1086 test('two calc terms for same declaration', twoCalcs); | 1357 test('two calc terms for same declaration', twoCalcs); |
| 1087 test('selector with many calc declarations', selectorWithCalcs); | 1358 test('selector with many calc declarations', selectorWithCalcs); |
| 1359 test('vendor prefixed calc', vendorPrefixedCalc); |
| 1088 }); | 1360 }); |
| 1089 } | 1361 } |
| 1090 | |
| OLD | NEW |