// 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.

// @dart = 2.9

library attribute_changed_callback_test;

import 'dart:async';
import 'dart:html';
import 'dart:js' as js;

import 'package:async_helper/async_minitest.dart';

import 'utils.dart';

class A extends HtmlElement {
  static final tag = 'x-a';
  factory A() => new Element.tag(tag);
  A.created() : super.created();

  static var attributeChangedInvocations = 0;

  void attributeChanged(name, oldValue, newValue) {
    attributeChangedInvocations++;
  }
}

class B extends HtmlElement {
  static final tag = 'x-b';
  factory B() => new Element.tag(tag);
  B.created() : super.created() {
    invocations.add('created');
  }

  static var invocations = [];

  Completer completer;

  void attributeChanged(name, oldValue, newValue) {
    invocations.add('$name: $oldValue => $newValue');
    if (completer != null) {
      completer.complete('value changed to $newValue');
      completer = null;
    }
  }
}

// Pump custom events polyfill events.
void customElementsTakeRecords() {
  if (js.context.hasProperty('CustomElements')) {
    js.context['CustomElements'].callMethod('takeRecords');
  }
}

main() async {
  // Adapted from Blink's fast/dom/custom/attribute-changed-callback test.

  await customElementsReady;
  document.registerElement2(A.tag, {'prototype': A});
  document.registerElement2(B.tag, {'prototype': B});

  group('fully_supported', () {
    test('transfer attribute changed callback', () {
      var element = new A();

      element.attributes['a'] = 'b';
      expect(A.attributeChangedInvocations, 1);
    });

    test('add, change and remove an attribute', () {
      var b = new B();

      B.invocations = [];
      b.attributes['data-s'] = 't';
      expect(B.invocations, ['data-s: null => t']);

      b.attributes['data-v'] = 'w';
      B.invocations = [];
      b.attributes['data-v'] = 'x';
      expect(B.invocations, ['data-v: w => x']);

      B.invocations = [];
      b.attributes['data-v'] = 'x';
      expect(B.invocations, []);

      b.attributes.remove('data-v');
      expect(B.invocations, ['data-v: x => null']);
    });

    test('add, change ID', () {
      B.invocations = [];

      var b = new B();
      var completer = new Completer();
      b.completer = completer;
      b.id = 'x';
      return completer.future
          .then((_) => expect(B.invocations, ['created', 'id: null => x']))
          .then((_) {
        B.invocations = [];
        var secondCompleter = new Completer();
        b.completer = secondCompleter;
        b.attributes.remove('id');
        return secondCompleter.future;
      }).then((_) => expect(B.invocations, ['id: x => null']));
    });
  });

  group('unsupported_on_polyfill', () {
    // If these tests start passing, don't remove the status suppression. Move
    // the tests to the fullYy_supported group.

    test('add, change classes', () {
      var b = new B();

      B.invocations = [];
      b.classes.toggle('u');
      expect(B.invocations, ['class: null => u']);
    });
  });
}
