// 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. import 'package:csslib/src/messages.dart'; import 'package:test/test.dart'; import 'testing.dart'; void compileAndValidate(String input, String generated) { var errors = []; var stylesheet = compileCss(input, errors: errors, opts: options); expect(errors.isEmpty, true, reason: errors.toString()); expect(prettyPrint(stylesheet), generated); } void simpleExtend() { compileAndValidate(r''' .error { border: 1px red; background-color: #fdd; } .seriousError { @extend .error; border-width: 3px; } ''', r''' .error, .seriousError { border: 1px #f00; background-color: #fdd; } .seriousError { border-width: 3px; }'''); } void complexSelectors() { compileAndValidate(r''' .error { border: 1px #f00; background-color: #fdd; } .error.intrusion { background-image: url("/image/hacked.png"); } .seriousError { @extend .error; border-width: 3px; } ''', r''' .error, .seriousError { border: 1px #f00; background-color: #fdd; } .error.intrusion, .seriousError.intrusion { background-image: url("/image/hacked.png"); } .seriousError { border-width: 3px; }'''); compileAndValidate(r''' a:hover { text-decoration: underline; } .hoverlink { @extend a:hover; } ''', r''' a:hover, .hoverlink { text-decoration: underline; } .hoverlink { }'''); } void multipleExtends() { compileAndValidate(r''' .error { border: 1px #f00; background-color: #fdd; } .attention { font-size: 3em; background-color: #ff0; } .seriousError { @extend .error; @extend .attention; border-width: 3px; } ''', r''' .error, .seriousError { border: 1px #f00; background-color: #fdd; } .attention, .seriousError { font-size: 3em; background-color: #ff0; } .seriousError { border-width: 3px; }'''); } void chaining() { compileAndValidate(r''' .error { border: 1px #f00; background-color: #fdd; } .seriousError { @extend .error; border-width: 3px; } .criticalError { @extend .seriousError; position: fixed; top: 10%; bottom: 10%; left: 10%; right: 10%; } ''', r''' .error, .seriousError, .criticalError { border: 1px #f00; background-color: #fdd; } .seriousError, .criticalError { border-width: 3px; } .criticalError { position: fixed; top: 10%; bottom: 10%; left: 10%; right: 10%; }'''); } void nestedSelectors() { compileAndValidate(r''' a { color: blue; &:hover { text-decoration: underline; } } #fake-links .link { @extend a; } ''', r''' a, #fake-links .link { color: #00f; } a:hover, #fake-links .link:hover { text-decoration: underline; } #fake-links .link { }'''); } void nestedMulty() { compileAndValidate(r''' .btn { display: inline-block; } input[type="checkbox"].toggle-button { color: red; + label { @extend .btn; } } ''', r''' .btn, input[type="checkbox"].toggle-button label { display: inline-block; } input[type="checkbox"].toggle-button { color: #f00; } input[type="checkbox"].toggle-button label { }'''); } void nWayExtends() { compileAndValidate( r''' .btn > .btn { margin-left: 5px; } input.second + label { @extend .btn; } ''', '.btn > .btn, ' 'input.second + label > .btn, ' '.btn > input.second + label, ' 'input.second + label > input.second + label, ' 'input.second + label > input.second + label {\n' ' margin-left: 5px;\n}\n' 'input.second + label {\n' '}'); // TODO(terry): Optimize merge selectors would be: // // .btn + .btn, input.second + label + .btn, input.second.btn + label { // margin-left: 5px; // } // input.second + label { // color: blue; // } compileAndValidate( r''' .btn + .btn { margin-left: 5px; } input.second + label { @extend .btn; color: blue; } ''', '.btn + .btn, ' 'input.second + label + .btn, ' '.btn + input.second + label, ' 'input.second + label + input.second + label, ' 'input.second + label + input.second + label {\n' ' margin-left: 5px;\n}\n' 'input.second + label {\n' ' color: #00f;\n}'); } void main() { test('Simple Extend', simpleExtend); test('complex', complexSelectors); test('multiple', multipleExtends); test('chaining', chaining); test('nested selectors', nestedSelectors); test('nested many selector sequences', nestedMulty); test('N-way extends', nWayExtends); }