<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
class TestElement extends HTMLElement {
  constructor() {
    super();
    this._internals = this.attachInternals();
  }

  get internals() {
    return this._internals;
  }
}
customElements.define("test-element", TestElement);

test(() => {
  let i = (new TestElement()).internals;

  assert_true(i.states instanceof DOMTokenList);
  assert_equals(i.states.length, 0);
  assert_false(i.states.contains('foo'));
  assert_equals(i.states.value, '');
  assert_equals(i.states.toString(), '');
}, 'DOMTokenList behavior of ElementInternals.states: Initial state');

test(() => {
  let i = (new TestElement()).internals;
  assert_throws_js(TypeError, () => { i.states.supports('foo'); });
  assert_throws_dom('SyntaxError', () => { i.states.add(''); });
  assert_throws_dom('InvalidCharacterError', () => { i.states.add('a\tb'); });
}, 'DOMTokenList behavior of ElementInternals.states: Exceptions');

test(() => {
  let i = (new TestElement()).internals;
  i.states.add('foo', 'bar', 'foo');
  assert_equals(i.states.length, 2);
  assert_true(i.states.contains('foo'));
  assert_true(i.states.contains('bar'));
  assert_equals(i.states.item(0), 'foo');
  assert_equals(i.states.item(1), 'bar');
  assert_equals(i.states[0], 'foo');
  assert_equals(i.states[1], 'bar');
  assert_equals(i.states.value, 'foo bar');
  i.states.remove('foo');
  assert_array_equals(i.states, ['bar']);
  assert_equals(i.states.value, 'bar');
  i.states.toggle('foo');
  assert_array_equals(i.states, ['bar', 'foo']);
  assert_equals(i.states.value, 'bar foo');
  i.states.replace('bar', 'baz');
  assert_array_equals(i.states, ['baz', 'foo']);
  assert_equals(i.states.value, 'baz foo');

  i.states.value = '  c u s t o o o o  m';
  assert_equals(i.states.length, 6);
  assert_array_equals(i.states, ['c', 'u', 's', 't', 'o', 'm']);

  i.states.value = '';
  // No throw for a token which can't be a CSS <ident>.
  i.states.add('foo)');
  assert_array_equals(i.states, ['foo)']);
}, 'DOMTokenList behavior of ElementInternals.states: Modifications');
</script>

