// 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 extend_test;

import 'package:csslib/src/messages.dart';
import 'package:test/test.dart';

import 'testing.dart';

void compileAndValidate(String input, String generated) {
  var errors = <Message>[];
  var stylesheet = compileCss(input, errors: errors, opts: options);
  expect(stylesheet != null, true);
  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);
}
