// Copyright (c) 2015, 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 web_components.test.custom_element_test;

import 'dart:async';
import 'dart:html';
import 'package:initialize/initialize.dart' as init;
import 'package:unittest/html_config.dart';
import 'package:unittest/unittest.dart';
import 'package:web_components/web_components.dart';

@CustomElement('basic-element')
class BasicElement extends HtmlElement {
  BasicElement.created() : super.created();

  factory BasicElement() => document.createElement('basic-element');
}

@CustomElement('child-element')
class ChildElement extends BasicElement {
  ChildElement.created() : super.created();

  factory ChildElement() => document.createElement('child-element');
}

@CustomElement('extended-element', extendsTag: 'input')
class ExtendedElement extends InputElement {
  ExtendedElement.created() : super.created();

  factory ExtendedElement() =>
      document.createElement('input', 'extended-element');
}

main() {
  useHtmlConfiguration();
  init.run().then((_) {
    var container = querySelector('#container') as DivElement;

    tearDown(() {
      container.children.clear();
    });

    test('basic custom element', () {
      expect(document.querySelector('basic-element') is BasicElement, isTrue);
      container.append(new BasicElement());
      container.appendHtml('<basic-element></basic-element>');
      // TODO(jakemac): after appendHtml elements are upgraded asynchronously,
      // why? https://github.com/dart-lang/web-components/issues/4
      return new Future(() {}).then((_) {
        var elements = container.querySelectorAll('basic-element');
        expect(elements.length, 2);
        for (var element in elements) {
          expect(element is BasicElement, isTrue);
        }
      });
    });

    test('child custom element', () {
      expect(document.querySelector('child-element') is ChildElement, isTrue);
      container.append(new ChildElement());
      container.appendHtml('<child-element></child-element>');
      // TODO(jakemac): after appendHtml elements are upgraded asynchronously,
      // why? https://github.com/dart-lang/web-components/issues/4
      return new Future(() {}).then((_) {
        var elements = container.querySelectorAll('child-element');
        expect(elements.length, 2);
        for (var element in elements) {
          expect(element is ChildElement, isTrue);
        }
      });
    });


    test('extends input element', () {
      expect(document.querySelector('input') is ExtendedElement, isTrue);
      container.append(new ExtendedElement());
      container.appendHtml('<input is="extended-element" />');
      // TODO(jakemac): after appendHtml elements are upgraded asynchronously,
      // why? https://github.com/dart-lang/web-components/issues/4
      return new Future(() {}).then((_) {
        var elements = container.querySelectorAll('input');
        expect(elements.length, 2);
        for (var element in elements) {
          expect(element is ExtendedElement, isTrue);
        }
      });
    });
  });
}
