// Copyright (c) 2011, 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.

import "package:expect/expect.dart";

/**
 * A test of simple runtime behavior on numbers, strings and lists with
 * a focus on both correct behavior and runtime errors.
 *
 * This file is written to use minimal type declarations to match a
 * typical dynamic language coding style.
 */
class CoreRuntimeTypesTest {
  static testMain() {
    testBooleanOperators();
    testRationalOperators();
    testIntegerOperators();
    testOperatorErrors();
    testRationalMethods();
    testIntegerMethods();
    testStringOperators();
    testStringMethods();
    testListOperators();
    testListMethods();
    testMapOperators();
    testMapMethods();
    testLiterals();
    testDateMethods();
  }

  static assertEquals(a, b) {
    Expect.equals(b, a);
  }

  static assertListEquals(List a, List b) {
    Expect.equals(b.length, a.length);
    for (int i = 0; i < a.length; i++) {
      Expect.equals(b[i], a[i]);
    }
  }

  static assertListContains(List a, List b) {
    a.sort((x, y) => x.compareTo(y));
    b.sort((x, y) => x.compareTo(y));
    assertListEquals(a, b);
  }

  static assertTypeError(void f(), [String? message]) {
    Expect.throws<Error>(
        f,
        (exception) =>
            (exception is TypeError) ||
            (exception is CastError) ||
            (exception is AssertionError) ||
            (exception is NoSuchMethodError) ||
            (exception is ArgumentError),
        message ?? "");
  }

  static testBooleanOperators() {
    var x = true, y = false;
    assertEquals(x, true);
    assertEquals(y, false);
    assertEquals(x, !y);
    assertEquals(!x, y);
  }

  static testRationalOperators() {
    var x = 10, y = 20;
    assertEquals(x + y, 30);
    assertEquals(x - y, -10);
    assertEquals(x * y, 200);
    assertEquals(x / y, 0.5);
    assertEquals(x ~/ y, 0);
    assertEquals(x % y, 10);
  }

  static testIntegerOperators() {
    var x = 18, y = 17;
    assertEquals(x | y, 19);
    assertEquals(x & y, 16);
    assertEquals(x ^ y, 3);
    assertEquals(2 >> 1, 1);
    assertEquals(1 << 1, 2);
  }

  static testOperatorErrors() {
    var objs = [
      1,
      '2',
      [3],
      null,
      true,
      new Map()
    ];
    for (var i = 0; i < objs.length; i++) {
      for (var j = i + 1; j < objs.length; j++) {
        testBinaryOperatorErrors(objs[i], objs[j]);
        testBinaryOperatorErrors(objs[j], objs[i]);
      }
      testUnaryOperatorErrors(objs[i]);
    }
  }

  static testBinaryOperatorErrors(dynamic x, dynamic y) {
    assertTypeError(() {
      x + y;
    }, "$x+$y");
    assertTypeError(() {
      x - y;
    }, "$x-$y");
    // String.* is the only non-same-type binary operator we have.
    if (x is! String && y is! int) {
      assertTypeError(() {
        x * y;
      }, "$x*$y");
    }
    assertTypeError(() {
      x / y;
    }, "$x/$y");
    assertTypeError(() {
      x | y;
    }, "$x|$y");
    assertTypeError(() {
      x ^ y;
    }, "$x^$y");
    assertTypeError(() {
      x & y;
    }, "$x&$y");
    assertTypeError(() {
      x << y;
    }, "$x<<$y");
    assertTypeError(() {
      x >> y;
    }, "$x>>$y");
    assertTypeError(() {
      x ~/ y;
    }, "$x~/$y");
    assertTypeError(() {
      x % y;
    }, "$x%$y");

    testComparisonOperatorErrors(x, y);
  }

  static testComparisonOperatorErrors(x, y) {
    assertEquals(x == y, false);
    assertEquals(x != y, true);
    assertTypeError(() {
      x < y;
    }, "$x<$y");
    assertTypeError(() {
      x <= y;
    }, "$x<=$y");
    assertTypeError(() {
      x > y;
    }, "$x>$y");
    assertTypeError(() {
      x >= y;
    }, "$x>=$y");
  }

  static testUnaryOperatorErrors(x) {
    if (x is! int) {
      assertTypeError(() {
        ~x;
      }, "~$x");
    }
    if (x is! num) {
      assertTypeError(() {
        -x;
      }, "-$x");
    }
    if (x is! bool) {
      assertTypeError(() {
        !x;
      }, "!$x");
    }
  }

  static testRationalMethods() {
    var x = 10.6;
    assertEquals(x.abs(), 10.6);
    assertEquals((-x).abs(), 10.6);
    assertEquals(x.round(), 11);
    assertEquals(x.floor(), 10);
    assertEquals(x.ceil(), 11);
  }

  // TODO(jimhug): Determine correct behavior for mixing ints and floats.
  static testIntegerMethods() {
    var y = 9;
    assertEquals(y.isEven, false);
    assertEquals(y.isOdd, true);
    assertEquals(y.toRadixString(2), '1001');
    assertEquals(y.toRadixString(3), '100');
    assertEquals(y.toRadixString(16), '9');
    assertEquals((0).toRadixString(16), '0');
    try {
      y.toRadixString(0);
      Expect.fail("Illegal radix 0 accepted.");
    } catch (e) {}
    try {
      y.toRadixString(-1);
      Expect.fail("Illegal radix -1 accepted.");
    } catch (e) {}
  }

  static testStringOperators() {
    dynamic s = "abcdef";
    assertEquals(s, "abcdef");
    assertEquals(s.codeUnitAt(0), 97);
    assertEquals(s[0], 'a');
    assertEquals(s.length, 6);
  }

  // TODO(jimhug): Fill out full set of string methods.
  static testStringMethods() {
    var s = "abcdef";
    assertEquals(s.isEmpty, false);
    assertEquals(s.isNotEmpty, true);
    assertEquals(s.startsWith("abc"), true);
    assertEquals(s.endsWith("def"), true);
    assertEquals(s.startsWith("aa"), false);
    assertEquals(s.endsWith("ff"), false);
    assertEquals(s.contains('cd', 0), true);
    assertEquals(s.contains('cd', 2), true);
    assertEquals(s.contains('cd', 3), false);
    assertEquals(s.indexOf('cd', 2), 2);
    assertEquals(s.indexOf('cd', 3), -1);
  }

  static testListOperators() {
    var a = [1, 2, 3, 4];
    assertEquals(a[0], 1);
    a[0] = 42;
    assertEquals(a[0], 42);
    assertEquals(a.length, 4);
  }

  // TODO(jimhug): Fill out full set of list methods.
  static testListMethods() {
    var a = [1, 2, 3, 4];
    assertEquals(a.isEmpty, false);
    assertEquals(a.length, 4);
    var exception = null;
    a.clear();
    assertEquals(a.length, 0);
  }

  static testMapOperators() {
    var d = new Map();
    d['a'] = 1;
    d['b'] = 2;
    assertEquals(d['a'], 1);
    assertEquals(d['b'], 2);
    assertEquals(d['c'], null);
  }

  static testMapMethods() {
    var d = new Map();
    d['a'] = 1;
    d['b'] = 2;
    assertEquals(d.containsValue(2), true);
    assertEquals(d.containsValue(3), false);
    assertEquals(d.containsKey('a'), true);
    assertEquals(d.containsKey('c'), false);
    assertEquals(d.keys.length, 2);
    assertEquals(d.values.length, 2);

    assertEquals(d.remove('c'), null);
    assertEquals(d.remove('b'), 2);
    assertEquals(d.keys.single, 'a');
    assertEquals(d.values.single, 1);

    d['c'] = 3;
    d['f'] = 4;
    assertEquals(d.keys.length, 3);
    assertEquals(d.values.length, 3);
    assertListContains(d.keys.toList(), ['a', 'c', 'f']);
    assertListContains(d.values.toList(), [1, 3, 4]);

    var count = 0;
    d.forEach((key, value) {
      count++;
      assertEquals(value, d[key]);
    });
    assertEquals(count, 3);

    d = {'a': 1, 'b': 2};
    assertEquals(d.containsValue(2), true);
    assertEquals(d.containsValue(3), false);
    assertEquals(d.containsKey('a'), true);
    assertEquals(d.containsKey('c'), false);
    assertEquals(d.keys.length, 2);
    assertEquals(d.values.length, 2);

    d['g'] = null;
    assertEquals(d.containsKey('g'), true);
    assertEquals(d['g'], null);
  }

  static testDateMethods() {
    var msec = 115201000;
    var d = new DateTime.fromMillisecondsSinceEpoch(msec, isUtc: true);
    assertEquals(d.second, 1);
    assertEquals(d.year, 1970);

    d = new DateTime.now();
    assertEquals(d.year >= 1970, true);
  }

  static testLiterals() {
    true.toString();
    1.0.toString();
    .5.toString();
    1.toString();
    if (false) {
      // Depends on http://b/4198808.
      null.toString();
    }
    '${null}'.toString();
    '${true}'.toString();
    '${false}'.toString();
    ''.toString();
    ''.endsWith('');
  }
}

main() {
  CoreRuntimeTypesTest.testMain();
}
