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

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}');
}

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);
}
