// 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:term_glyph/term_glyph.dart' as glyph; import 'package:test/test.dart'; import 'testing.dart'; /// Test for unsupported font-weights values of bolder, lighter and inherit. void testUnsupportedFontWeights() { var errors = []; // TODO(terry): Need to support bolder. // font-weight value bolder. var input = '.foobar { font-weight: bolder; }'; var stylesheet = parseCss(input, errors: errors); expect(errors.isEmpty, false); expect(errors[0].toString(), ''' error on line 1, column 24: Unknown property value bolder , 1 | .foobar { font-weight: bolder; } | ^^^^^^ \''''); expect(prettyPrint(stylesheet), r''' .foobar { font-weight: bolder; }'''); // TODO(terry): Need to support lighter. // font-weight value lighter. input = '.foobar { font-weight: lighter; }'; stylesheet = parseCss(input, errors: errors..clear()); expect(errors.isEmpty, false); expect(errors[0].toString(), ''' error on line 1, column 24: Unknown property value lighter , 1 | .foobar { font-weight: lighter; } | ^^^^^^^ \''''); expect(prettyPrint(stylesheet), r''' .foobar { font-weight: lighter; }'''); // TODO(terry): Need to support inherit. // font-weight value inherit. input = '.foobar { font-weight: inherit; }'; stylesheet = parseCss(input, errors: errors..clear()); expect(errors.isEmpty, false); expect(errors[0].toString(), ''' error on line 1, column 24: Unknown property value inherit , 1 | .foobar { font-weight: inherit; } | ^^^^^^^ \''''); expect(prettyPrint(stylesheet), r''' .foobar { font-weight: inherit; }'''); } /// Test for unsupported line-height values of units other than px, pt and /// inherit. void testUnsupportedLineHeights() { var errors = []; // line-height value in percentage unit. var input = '.foobar { line-height: 120%; }'; var stylesheet = parseCss(input, errors: errors); expect(errors.isEmpty, false); expect(errors[0].toString(), ''' error on line 1, column 24: Unexpected value for line-height , 1 | .foobar { line-height: 120%; } | ^^^^ \''''); expect(prettyPrint(stylesheet), r''' .foobar { line-height: 120%; }'''); // TODO(terry): Need to support all units. // line-height value in cm unit. input = '.foobar { line-height: 20cm; }'; stylesheet = parseCss(input, errors: errors..clear()); expect(errors.isEmpty, false); expect(errors[0].toString(), ''' error on line 1, column 24: Unexpected unit for line-height , 1 | .foobar { line-height: 20cm; } | ^^^^ \''''); expect(prettyPrint(stylesheet), r''' .foobar { line-height: 20cm; }'''); // TODO(terry): Need to support inherit. // line-height value inherit. input = '.foobar { line-height: inherit; }'; stylesheet = parseCss(input, errors: errors..clear()); expect(errors.isEmpty, false); expect(errors[0].toString(), ''' error on line 1, column 24: Unknown property value inherit , 1 | .foobar { line-height: inherit; } | ^^^^^^^ \''''); expect(prettyPrint(stylesheet), r''' .foobar { line-height: inherit; }'''); } /// Test for bad selectors. void testBadSelectors() { var errors = []; // Invalid id selector. var input = '# foo { color: #ff00ff; }'; parseCss(input, errors: errors); expect(errors, isNotEmpty); expect(errors[0].toString(), ''' error on line 1, column 1: Not a valid ID selector expected #id , 1 | # foo { color: #ff00ff; } | ^ \''''); // Invalid class selector. input = '. foo { color: #ff00ff; }'; parseCss(input, errors: errors..clear()); expect(errors, isNotEmpty); expect(errors[0].toString(), ''' error on line 1, column 1: Not a valid class selector expected .className , 1 | . foo { color: #ff00ff; } | ^ \''''); } /// Test for bad hex values. void testBadHexValues() { var errors = []; // Invalid hex value. var input = '.foobar { color: #AH787; }'; var stylesheet = parseCss(input, errors: errors); expect(errors.isEmpty, false); expect(errors[0].toString(), ''' error on line 1, column 18: Bad hex number , 1 | .foobar { color: #AH787; } | ^^^^^^ \''''); expect(prettyPrint(stylesheet), r''' .foobar { color: #AH787; }'''); // Bad color constant. input = '.foobar { color: redder; }'; stylesheet = parseCss(input, errors: errors..clear()); expect(errors.isEmpty, false); expect(errors[0].toString(), ''' error on line 1, column 18: Unknown property value redder , 1 | .foobar { color: redder; } | ^^^^^^ \''''); expect(prettyPrint(stylesheet), r''' .foobar { color: redder; }'''); // Bad hex color #ffffff. input = '.foobar { color: # ffffff; }'; stylesheet = parseCss(input, errors: errors..clear()); expect(errors.isEmpty, false); expect(errors[0].toString(), ''' error on line 1, column 18: Expected hex number , 1 | .foobar { color: # ffffff; } | ^ \''''); expect(prettyPrint(stylesheet), r''' .foobar { color: # ffffff; }'''); // Bad hex color #123fff. input = '.foobar { color: # 123fff; }'; stylesheet = parseCss(input, errors: errors..clear()); expect(errors.isEmpty, false); expect(errors[0].toString(), ''' error on line 1, column 18: Expected hex number , 1 | .foobar { color: # 123fff; } | ^ \''''); // Formating is off with an extra space. However, the entire value is bad // and isn't processed anyway. expect(prettyPrint(stylesheet), r''' .foobar { color: # 123 fff; }'''); } void testBadUnicode() { var errors = []; final input = ''' @font-face { src: url(fonts/BBCBengali.ttf) format("opentype"); unicode-range: U+400-200; }'''; parseCss(input, errors: errors); expect(errors.isEmpty, false); expect( errors[0].toString(), 'error on line 3, column 20: unicode first range can not be greater than ' 'last\n' ' ,\n' '3 | unicode-range: U+400-200;\n' ' | ^^^^^^^\n' ' \''); final input2 = ''' @font-face { src: url(fonts/BBCBengali.ttf) format("opentype"); unicode-range: U+12FFFF; }'''; parseCss(input2, errors: errors..clear()); expect(errors.isEmpty, false); expect( errors[0].toString(), 'error on line 3, column 20: unicode range must be less than 10FFFF\n' ' ,\n' '3 | unicode-range: U+12FFFF;\n' ' | ^^^^^^\n' ' \''); } void testBadNesting() { var errors = []; // Test for bad declaration in a nested rule. final input = ''' div { width: 20px; span + ul { color: blue; } span + ul > #aaaa { color: #ffghghgh; } background-color: red; } '''; parseCss(input, errors: errors); expect(errors.length, 1); var errorMessage = messages.messages[0]; expect(errorMessage.message, contains('Bad hex number')); expect(errorMessage.span, isNotNull); expect(errorMessage.span!.start.line, 4); expect(errorMessage.span!.start.column, 11); expect(errorMessage.span!.text, '#ffghghgh'); // Test for bad selector syntax. final input2 = ''' div { span + ul #aaaa > (3333) { color: #ffghghgh; } } '''; parseCss(input2, errors: errors..clear()); expect(errors.length, 4); errorMessage = messages.messages[0]; expect(errorMessage.message, contains(':, but found +')); expect(errorMessage.span, isNotNull); expect(errorMessage.span!.start.line, 1); expect(errorMessage.span!.start.column, 7); expect(errorMessage.span!.text, '+'); errorMessage = messages.messages[1]; expect(errorMessage.message, contains('Unknown property value ul')); expect(errorMessage.span, isNotNull); expect(errorMessage.span!.start.line, 1); expect(errorMessage.span!.start.column, 9); expect(errorMessage.span!.text, 'ul'); errorMessage = messages.messages[2]; expect(errorMessage.message, contains('expected }, but found >')); expect(errorMessage.span, isNotNull); expect(errorMessage.span!.start.line, 1); expect(errorMessage.span!.start.column, 18); expect(errorMessage.span!.text, '>'); errorMessage = messages.messages[3]; expect(errorMessage.message, contains('premature end of file unknown CSS')); expect(errorMessage.span, isNotNull); expect(errorMessage.span!.start.line, 1); expect(errorMessage.span!.start.column, 20); expect(errorMessage.span!.text, '('); // Test for missing close braces and bad declaration. final input3 = ''' div { span { color: #green; } '''; parseCss(input3, errors: errors..clear()); expect(errors.length, 2); errorMessage = messages.messages[0]; expect(errorMessage.message, contains('Bad hex number')); expect(errorMessage.span, isNotNull); expect(errorMessage.span!.start.line, 2); expect(errorMessage.span!.start.column, 11); expect(errorMessage.span!.text, '#green'); errorMessage = messages.messages[1]; expect(errorMessage.message, contains('expected }, but found end of file')); expect(errorMessage.span, isNotNull); expect(errorMessage.span!.start.line, 3); expect(errorMessage.span!.start.column, 1); expect(errorMessage.span!.text, '\n'); } void main() { glyph.ascii = true; test('font-weight value errors', testUnsupportedFontWeights); test('line-height value errors', testUnsupportedLineHeights); test('bad selectors', testBadSelectors); test('bad Hex values', testBadHexValues); test('bad unicode ranges', testBadUnicode); test('nested rules', testBadNesting); }