// 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(x, 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() {
    var s = "abcdef";
    assertEquals(s, "abcdef");
    assertEquals(s.codeUnitAt(0), 97);
    assertEquals(s[0], 'a');
    assertEquals(s.length, 6);
    assertTypeError(() {
      s[null];
    });
  }

  // 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();
}
