| // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| library var_test; |
| |
| import 'package:unittest/unittest.dart'; |
| import 'package:csslib/parser.dart'; |
| import 'package:csslib/visitor.dart'; |
| import 'testing.dart'; |
| |
| void simpleVar() { |
| final errors = []; |
| final input = ''':root { |
| var-color-background: red; |
| var-color-foreground: blue; |
| |
| var-a: var(b); |
| var-b: var(c); |
| var-c: #00ff00; |
| } |
| .testIt { |
| color: var(color-foreground); |
| background: var(color-background); |
| } |
| '''; |
| |
| final generated = ''':root { |
| var-color-background: #f00; |
| var-color-foreground: #00f; |
| var-a: var(b); |
| var-b: var(c); |
| var-c: #0f0; |
| } |
| .testIt { |
| color: var(color-foreground); |
| background: var(color-background); |
| }'''; |
| |
| var stylesheet = compileCss(input, errors: errors, |
| opts: ['--no-colors', 'memory']); |
| |
| expect(stylesheet != null, true); |
| expect(errors.isEmpty, true, reason: errors.toString()); |
| expect(prettyPrint(stylesheet), generated); |
| } |
| |
| void expressionsVar() { |
| final errors = []; |
| final input = ''':root { |
| var-color-background: red; |
| var-color-foreground: blue; |
| |
| var-a: var(b); |
| var-b: var(c); |
| var-c: #00ff00; |
| |
| var-image: url(test.png); |
| |
| var-b-width: 20cm; |
| var-m-width: 33%; |
| var-b-height: 30EM; |
| var-width: .6in; |
| var-length: 1.2in; |
| var-web-stuff: -10Px; |
| var-rgba: rgba(10,20,255); |
| var-transition: color 0.4s; |
| var-transform: rotate(20deg); |
| var-content: "✔"; |
| var-text-shadow: 0 -1px 0 #bfbfbf; |
| var-font-family: Gentium; |
| var-src: url("http://example.com/fonts/Gentium.ttf"); |
| var-src-1: local(Gentium Bold), local(Gentium-Bold), url("GentiumBold.ttf"); |
| var-unicode-range: U+000-49F, U+2000-27FF, U+2900-2BFF, U+1D400-1D7FF; |
| var-unicode-range-1: U+0A-FF, U+980-9FF, U+????, U+3???; |
| var-grid-columns: 10px ("content" 1fr 10px) [4]; |
| } |
| |
| .testIt { |
| color: var(color-foreground); |
| background: var(c); |
| background-image: var(image); |
| |
| border-width: var(b-width); |
| margin-width: var(m-width); |
| border-height: var(b-height); |
| width: var(width); |
| length: var(length); |
| -web-stuff: var(web-stuff); |
| background-color: var(rgba); |
| |
| transition: var(transition); |
| transform: var(transform); |
| content: var(content); |
| text-shadow: var(text-shadow); |
| } |
| |
| @font-face { |
| font-family: var(font-family); |
| src: var(src); |
| unicode-range: var(unicode-range); |
| } |
| |
| @font-face { |
| font-family: var(font-family); |
| src: var(src-1); |
| unicode-range: var(unicode-range-1); |
| } |
| |
| .foobar { |
| grid-columns: var(grid-columns); |
| } |
| '''; |
| |
| final generated = ''':root { |
| var-color-background: #f00; |
| var-color-foreground: #00f; |
| var-a: var(b); |
| var-b: var(c); |
| var-c: #0f0; |
| var-image: url("test.png"); |
| var-b-width: 20cm; |
| var-m-width: 33%; |
| var-b-height: 30em; |
| var-width: .6in; |
| var-length: 1.2in; |
| var-web-stuff: -10px; |
| var-rgba: rgba(10, 20, 255); |
| var-transition: color 0.4s; |
| var-transform: rotate(20deg); |
| var-content: "✔"; |
| var-text-shadow: 0 -1px 0 #bfbfbf; |
| var-font-family: Gentium; |
| var-src: url("http://example.com/fonts/Gentium.ttf"); |
| var-src-1: local(Gentium Bold), local(Gentium-Bold), url("GentiumBold.ttf"); |
| var-unicode-range: U+000-49F, U+2000-27FF, U+2900-2BFF, U+1D400-1D7FF; |
| var-unicode-range-1: U+0A-FF, U+980-9FF, U+????, U+3???; |
| var-grid-columns: 10px ("content" 1fr 10px) [4]; |
| } |
| .testIt { |
| color: var(color-foreground); |
| background: var(c); |
| background-image: var(image); |
| border-width: var(b-width); |
| margin-width: var(m-width); |
| border-height: var(b-height); |
| width: var(width); |
| length: var(length); |
| -web-stuff: var(web-stuff); |
| background-color: var(rgba); |
| transition: var(transition); |
| transform: var(transform); |
| content: var(content); |
| text-shadow: var(text-shadow); |
| } |
| @font-face { |
| font-family: var(font-family); |
| src: var(src); |
| unicode-range: var(unicode-range); |
| } |
| @font-face { |
| font-family: var(font-family); |
| src: var(src-1); |
| unicode-range: var(unicode-range-1); |
| } |
| .foobar { |
| grid-columns: var(grid-columns); |
| }'''; |
| |
| var stylesheet = compileCss(input, errors: errors, |
| opts: ['--no-colors', 'memory']); |
| |
| expect(stylesheet != null, true); |
| expect(errors.isEmpty, true, reason: errors.toString()); |
| expect(prettyPrint(stylesheet), generated); |
| } |
| |
| void defaultVar() { |
| final errors = []; |
| final input = ''' |
| :root { |
| var-color-background: red; |
| var-color-foreground: blue; |
| |
| var-a: var(b); |
| var-b: var(c); |
| var-c: #00ff00; |
| |
| var-image: url(test.png); |
| |
| var-b-width: 20cm; |
| var-m-width: 33%; |
| var-b-height: 30EM; |
| } |
| |
| .test { |
| background-color: var(test, orange); |
| } |
| |
| body { |
| background: var(a) var(image) no-repeat right top; |
| } |
| |
| div { |
| background: var(color-background) url('img_tree.png') no-repeat right top; |
| } |
| |
| .test-2 { |
| background: var(color-background) var(image-2, url('img_1.png')) |
| no-repeat right top; |
| } |
| |
| .test-3 { |
| background: var(color-background) var(image-2) no-repeat right top; |
| } |
| |
| .test-4 { |
| background: #ffff00 var(image) no-repeat right top; |
| } |
| |
| .test-5 { |
| background: var(test-color, var(a)) var(image) no-repeat right top; |
| } |
| |
| .test-6 { |
| border: red var(a-1, solid 20px); |
| } |
| '''; |
| |
| final generated = ''':root { |
| var-color-background: #f00; |
| var-color-foreground: #00f; |
| var-a: var(b); |
| var-b: var(c); |
| var-c: #0f0; |
| var-image: url("test.png"); |
| var-b-width: 20cm; |
| var-m-width: 33%; |
| var-b-height: 30em; |
| } |
| .test { |
| background-color: var(test, #ffa500); |
| } |
| body { |
| background: var(a) var(image) no-repeat right top; |
| } |
| div { |
| background: var(color-background) url("img_tree.png") no-repeat right top; |
| } |
| .test-2 { |
| background: var(color-background) var(image-2, url("img_1.png")) no-repeat right top; |
| } |
| .test-3 { |
| background: var(color-background) var(image-2) no-repeat right top; |
| } |
| .test-4 { |
| background: #ff0 var(image) no-repeat right top; |
| } |
| .test-5 { |
| background: var(test-color, var(a)) var(image) no-repeat right top; |
| } |
| .test-6 { |
| border: #f00 var(a-1, solid 20px); |
| }'''; |
| |
| var stylesheet = compileCss(input, errors: errors, |
| opts: ['--no-colors', 'memory']); |
| |
| expect(stylesheet != null, true); |
| expect(errors.isEmpty, true, reason: errors.toString()); |
| expect(prettyPrint(stylesheet), generated); |
| } |
| |
| void cyclesVar() { |
| final errors = []; |
| final input = ''':root { |
| var-color-background: red; |
| var-color-foreground: blue; |
| |
| var-a: var(b); |
| var-b: var(c); |
| var-c: #00ff00; |
| |
| var-one: var(two); |
| var-two: var(one); |
| |
| var-four: var(five); |
| var-five: var(six); |
| var-six: var(four); |
| |
| var-def-1: var(def-2); |
| var-def-2: var(def-3); |
| var-def-3: var(def-2); |
| } |
| .testIt { |
| color: var(color-foreground); |
| background: var(color-background); |
| } |
| .test-2 { |
| color: var(one); |
| } |
| '''; |
| |
| final generated = ''':root { |
| var-color-background: #f00; |
| var-color-foreground: #00f; |
| var-a: var(b); |
| var-b: var(c); |
| var-c: #0f0; |
| } |
| .testIt { |
| color: var(color-foreground); |
| background: var(color-background); |
| } |
| .test-2 { |
| color: var(one); |
| }'''; |
| |
| var stylesheet = compileCss(input, errors: errors, |
| opts: ['--no-colors', '--warnings_as_errors', 'memory']); |
| |
| expect(stylesheet != null, true); |
| expect(errors.length, 8, reason: errors.toString()); |
| int testBitMap = 0; |
| var errorStrings = [ |
| 'error :14:3: var cycle detected var-six\n' |
| ' var-six: var(four);\n' |
| ' ^^^^^^^^^^^^^^^^^^', |
| 'error :18:3: var cycle detected var-def-3\n' |
| ' var-def-3: var(def-2);\n' |
| ' ^^^^^^^^^^^^^^^^^^^^^', |
| 'error :10:3: var cycle detected var-two\n' |
| ' var-two: var(one);\n' |
| ' ^^^^^^^^^^^^^^^^^', |
| 'error :17:3: var cycle detected var-def-2\n' |
| ' var-def-2: var(def-3);\n' |
| ' ^^^^^^^^^^^^^^^^^^^^^', |
| 'error :16:3: var cycle detected var-def-1\n' |
| ' var-def-1: var(def-2);\n' |
| ' ^^^^^^^^^^^^^^^^^^^^^', |
| 'error :13:3: var cycle detected var-five\n' |
| ' var-five: var(six);\n' |
| ' ^^^^^^^^^^^^^^^^^^', |
| 'error :9:3: var cycle detected var-one\n' |
| ' var-one: var(two);\n' |
| ' ^^^^^^^^^^^^^^^^^', |
| 'error :12:3: var cycle detected var-four\n' |
| ' var-four: var(five);\n' |
| ' ^^^^^^^^^^^^^^^^^^^' |
| ]; |
| outer: for (var error in errors) { |
| var errorString = error.toString(); |
| for (int i = 0; i < 8; i++) { |
| if (errorString == errorStrings[i]) { |
| testBitMap |= 1 << i; |
| continue outer; |
| } |
| } |
| fail("Unexpected error string: $errorString"); |
| } |
| expect(testBitMap, equals((1 << 8) - 1)); |
| expect(prettyPrint(stylesheet), generated); |
| } |
| |
| parserVar() { |
| final errors = []; |
| final input = ''':root { |
| var-color-background: red; |
| var-color-foreground: blue; |
| |
| var-a: var(b); |
| var-b: var(c); |
| var-c: #00ff00; |
| |
| var-image: url(test.png); |
| |
| var-b-width: 20cm; |
| var-m-width: 33%; |
| var-b-height: 30EM; |
| var-width: .6in; |
| var-length: 1.2in; |
| var-web-stuff: -10Px; |
| var-rgba: rgba(10,20,255); |
| var-transition: color 0.4s; |
| var-transform: rotate(20deg); |
| var-content: "✔"; |
| var-text-shadow: 0 -1px 0 #bfbfbf; |
| var-font-family: Gentium; |
| var-src: url("http://example.com/fonts/Gentium.ttf"); |
| var-src-1: local(Gentium Bold), local(Gentium-Bold), url("GentiumBold.ttf"); |
| var-unicode-range: U+000-49F, U+2000-27FF, U+2900-2BFF, U+1D400-1D7FF; |
| var-unicode-range-1: U+0A-FF, U+980-9FF, U+????, U+3???; |
| var-grid-columns: 10px ("content" 1fr 10px) [4]; |
| } |
| |
| .testIt { |
| color: var(color-foreground); |
| background: var(c); |
| background-image: var(image); |
| |
| border-width: var(b-width); |
| margin-width: var(m-width); |
| border-height: var(b-height); |
| width: var(width); |
| length: var(length); |
| -web-stuff: var(web-stuff); |
| background-color: var(rgba); |
| |
| transition: var(transition); |
| transform: var(transform); |
| content: var(content); |
| text-shadow: var(text-shadow); |
| } |
| |
| @font-face { |
| font-family: var(font-family); |
| src: var(src); |
| unicode-range: var(unicode-range); |
| } |
| |
| @font-face { |
| font-family: var(font-family); |
| src: var(src-1); |
| unicode-range: var(unicode-range-1); |
| } |
| |
| .foobar { |
| grid-columns: var(grid-columns); |
| } |
| '''; |
| |
| final generated = ''':root { |
| var-color-background: #f00; |
| var-color-foreground: #00f; |
| var-a: var(b); |
| var-b: var(c); |
| var-c: #0f0; |
| var-image: url("test.png"); |
| var-b-width: 20cm; |
| var-m-width: 33%; |
| var-b-height: 30em; |
| var-width: .6in; |
| var-length: 1.2in; |
| var-web-stuff: -10px; |
| var-rgba: rgba(10, 20, 255); |
| var-transition: color 0.4s; |
| var-transform: rotate(20deg); |
| var-content: "✔"; |
| var-text-shadow: 0 -1px 0 #bfbfbf; |
| var-font-family: Gentium; |
| var-src: url("http://example.com/fonts/Gentium.ttf"); |
| var-src-1: local(Gentium Bold), local(Gentium-Bold), url("GentiumBold.ttf"); |
| var-unicode-range: U+000-49F, U+2000-27FF, U+2900-2BFF, U+1D400-1D7FF; |
| var-unicode-range-1: U+0A-FF, U+980-9FF, U+????, U+3???; |
| var-grid-columns: 10px ("content" 1fr 10px) [4]; |
| } |
| .testIt { |
| color: var(color-foreground); |
| background: var(c); |
| background-image: var(image); |
| border-width: var(b-width); |
| margin-width: var(m-width); |
| border-height: var(b-height); |
| width: var(width); |
| length: var(length); |
| -web-stuff: var(web-stuff); |
| background-color: var(rgba); |
| transition: var(transition); |
| transform: var(transform); |
| content: var(content); |
| text-shadow: var(text-shadow); |
| } |
| @font-face { |
| font-family: var(font-family); |
| src: var(src); |
| unicode-range: var(unicode-range); |
| } |
| @font-face { |
| font-family: var(font-family); |
| src: var(src-1); |
| unicode-range: var(unicode-range-1); |
| } |
| .foobar { |
| grid-columns: var(grid-columns); |
| }'''; |
| |
| var stylesheet = parseCss(input, errors: errors, |
| opts: ['--no-colors', 'memory']); |
| |
| expect(stylesheet != null, true); |
| expect(errors.isEmpty, true, reason: errors.toString()); |
| expect(prettyPrint(stylesheet), generated); |
| } |
| |
| testVar() { |
| final errors = []; |
| final input = ''' |
| @color-background: red; |
| @color-foreground: blue; |
| |
| .test { |
| background-color: var(color-background); |
| color: var(color-foreground); |
| } |
| '''; |
| final generated = ''' |
| var-color-background: #f00; |
| var-color-foreground: #00f; |
| |
| .test { |
| background-color: var(color-background); |
| color: var(color-foreground); |
| }'''; |
| |
| var stylesheet = parseCss(input, errors: errors, |
| opts: ['--no-colors', 'memory']); |
| |
| expect(stylesheet != null, true); |
| expect(errors.isEmpty, true, reason: errors.toString()); |
| expect(prettyPrint(stylesheet), generated); |
| |
| stylesheet = compileCss(input, errors: errors..clear(), |
| opts: ['--no-colors', 'memory']); |
| |
| expect(stylesheet != null, true); |
| expect(errors.isEmpty, true, reason: errors.toString()); |
| expect(prettyPrint(stylesheet), generated); |
| |
| final input2 = ''' |
| @color-background: red; |
| @color-foreground: blue; |
| |
| .test { |
| background-color: @color-background; |
| color: @color-foreground; |
| } |
| '''; |
| final generated2 = '''var-color-background: #f00; |
| var-color-foreground: #00f; |
| |
| .test { |
| background-color: var(color-background); |
| color: var(color-foreground); |
| }'''; |
| |
| stylesheet = parseCss(input, errors: errors..clear(), |
| opts: ['--no-colors', 'memory']); |
| |
| expect(stylesheet != null, true); |
| expect(errors.isEmpty, true, reason: errors.toString()); |
| expect(prettyPrint(stylesheet), generated2); |
| |
| stylesheet = compileCss(input2, errors: errors..clear(), |
| opts: ['--no-colors', 'memory', '--no-less']); |
| |
| expect(stylesheet != null, true); |
| expect(errors.isEmpty, true, reason: errors.toString()); |
| expect(prettyPrint(stylesheet), generated2); |
| } |
| |
| testLess() { |
| final errors = []; |
| final input = ''' |
| @color-background: red; |
| @color-foreground: blue; |
| |
| .test { |
| background-color: var(color-background); |
| color: var(color-foreground); |
| } |
| '''; |
| final generated = '''var-color-background: #f00; |
| var-color-foreground: #00f; |
| |
| .test { |
| background-color: var(color-background); |
| color: var(color-foreground); |
| }'''; |
| |
| var stylesheet = parseCss(input, errors: errors, |
| opts: ['--no-colors', 'memory']); |
| |
| expect(stylesheet != null, true); |
| expect(errors.isEmpty, true, reason: errors.toString()); |
| expect(prettyPrint(stylesheet), generated); |
| |
| stylesheet = compileCss(input, errors: errors..clear(), |
| opts: ['--no-colors', 'memory']); |
| |
| expect(stylesheet != null, true); |
| expect(errors.isEmpty, true, reason: errors.toString()); |
| expect(prettyPrint(stylesheet), generated); |
| |
| final input2 = ''' |
| @color-background: red; |
| @color-foreground: blue; |
| |
| .test { |
| background-color: @color-background; |
| color: @color-foreground; |
| } |
| '''; |
| final generated2 = '''var-color-background: #f00; |
| var-color-foreground: #00f; |
| |
| .test { |
| background-color: var(color-background); |
| color: var(color-foreground); |
| }'''; |
| |
| stylesheet = parseCss(input, errors: errors..clear(), |
| opts: ['--no-colors', 'memory']); |
| |
| expect(stylesheet != null, true); |
| expect(errors.isEmpty, true, reason: errors.toString()); |
| expect(prettyPrint(stylesheet), generated2); |
| |
| stylesheet = compileCss(input2, errors: errors..clear(), |
| opts: ['--no-colors', 'memory', '--no-less']); |
| |
| expect(stylesheet != null, true); |
| expect(errors.isEmpty, true, reason: errors.toString()); |
| expect(prettyPrint(stylesheet), generated2); |
| } |
| |
| void polyfill() { |
| var errors = []; |
| var input = r''' |
| @color-background: red; |
| @color-foreground: blue; |
| .test { |
| background-color: @color-background; |
| color: @color-foreground; |
| }'''; |
| |
| var generated = r'''.test { |
| background-color: #f00; |
| color: #00f; |
| }'''; |
| |
| var stylesheet = compileCss(input, errors: errors, |
| opts: ['--no-colors', 'memory'], polyfill: true); |
| |
| expect(stylesheet != null, true); |
| expect(errors.isEmpty, true, reason: errors.toString()); |
| expect(prettyPrint(stylesheet), generated); |
| } |
| |
| |
| |
| main() { |
| test('Simple var', simpleVar); |
| test('Expressions var', expressionsVar); |
| test('Default value in var()', defaultVar); |
| test('CSS Parser only var', parserVar); |
| test('Var syntax', testVar); |
| test('Cycles var', cyclesVar); |
| test('Less syntax', testLess); |
| test('Polyfill', polyfill); |
| } |