// Copyright (c) 2020, 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 KeyboardEventTest;

import 'dart:html';

import 'package:expect/legacy/minitest.dart'; // ignore: deprecated_member_use_from_same_package

// Test that we are correctly determining keyCode and charCode uniformly across
// browsers.

void testKeyboardEventConstructor() {
  new KeyboardEvent('keyup');
}

void keydownHandlerTest(KeyEvent e) {
  expect(e.charCode, 0);
}

void testKeys() {
  var subscription =
      KeyboardEventStream.onKeyDown(document.body!).listen(keydownHandlerTest);
  var subscription2 =
      KeyEvent.keyDownEvent.forTarget(document.body).listen(keydownHandlerTest);
  var subscription3 =
      document.body!.onKeyDown.listen((e) => print('regular listener'));
  subscription.cancel();
  subscription2.cancel();
  subscription3.cancel();
}

void testConstructKeyEvent() {
  int handlerCallCount = 0;
  CustomStream<KeyEvent> stream = KeyEvent.keyPressEvent
      .forTarget(document.body!) as CustomStream<KeyEvent>;
  var subscription = stream.listen((keyEvent) {
    expect(keyEvent.charCode, 97);
    expect(keyEvent.keyCode, 65);
    handlerCallCount++;
  });
  var k = new KeyEvent('keypress', keyCode: 65, charCode: 97);
  stream.add(k);
  subscription.cancel();
  // Capital "A":
  stream.add(new KeyEvent('keydown', keyCode: 16, charCode: 0));

  subscription = stream.listen((keyEvent) {
    expect(keyEvent.charCode, 65);
    expect(keyEvent.keyCode, 65);
    handlerCallCount++;
  });
  stream.add(new KeyEvent('keypress', keyCode: 65, charCode: 65));
  subscription.cancel();

  expect(handlerCallCount, 2);
}

void testKeyEventSequence() {
  int handlerCallCount = 0;
  // Press "?" by simulating "shift" and then the key that has "/" and "?" on
  // it.
  CustomStream<KeyEvent> streamDown =
      KeyEvent.keyDownEvent.forTarget(document.body!) as CustomStream<KeyEvent>;
  CustomStream<KeyEvent> streamPress = KeyEvent.keyPressEvent
      .forTarget(document.body!) as CustomStream<KeyEvent>;
  CustomStream<KeyEvent> streamUp =
      KeyEvent.keyUpEvent.forTarget(document.body!) as CustomStream<KeyEvent>;

  var subscription = streamDown.listen((keyEvent) {
    expect(keyEvent.keyCode, predicate([16, 191].contains));
    expect(keyEvent.charCode, 0);
    handlerCallCount++;
  });

  var subscription2 = streamPress.listen((keyEvent) {
    expect(keyEvent.keyCode, 23);
    expect(keyEvent.charCode, 63);
    handlerCallCount++;
  });

  var subscription3 = streamUp.listen((keyEvent) {
    expect(keyEvent.keyCode, predicate([16, 191].contains));
    expect(keyEvent.charCode, 0);
    handlerCallCount++;
  });

  streamDown.add(new KeyEvent('keydown', keyCode: 16, charCode: 0));
  streamDown.add(new KeyEvent('keydown', keyCode: 191, charCode: 0));

  streamPress.add(new KeyEvent('keypress', keyCode: 23, charCode: 63));

  streamUp.add(new KeyEvent('keyup', keyCode: 191, charCode: 0));
  streamUp.add(new KeyEvent('keyup', keyCode: 16, charCode: 0));
  subscription.cancel();
  subscription2.cancel();
  subscription3.cancel();

  expect(handlerCallCount, 5);
}

void testKeyEventKeyboardEvent() {
  int handlerCallCount = 0;
  window.onKeyDown.listen((event) {
    expect(event.keyCode, 16);
    handlerCallCount++;
  });
  CustomStream<KeyEvent> streamDown =
      KeyEvent.keyDownEvent.forTarget(document.body!) as CustomStream<KeyEvent>;
  streamDown.add(new KeyEvent('keydown', keyCode: 16, charCode: 0));
  expect(handlerCallCount, 1);
}

main() {
  testKeyboardEventConstructor();
  testKeys();
  testConstructKeyEvent();
  testKeyEventSequence();
  testKeyEventKeyboardEvent();
}
