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

// Test of apparent compile-time nature of constant evaluation. Constant Lists,
// Maps and other objects should be identical independent of formation.

import "package:expect/expect.dart";

abstract class Roman {
  static const I = 1;
  static const II = 2;
  static const III = 3;
  static const IV = 4;
  static const V = 5;

  static const VivaItalia = const {"green": 1, "red": 3, "white": 2};
}

class Point {
  static const int zero = 0;

  static const origin = const Point(0, 0);
  static const origin2 = const Point(zero, Roman.IV - 4);

  const Point(x, y)
      : x_ = x,
        y_ = y;
  const Point.X(x)
      : x_ = x,
        y_ = Roman.V - Roman.II - 3;

  bool operator ==(final dynamic other) {
    return (this.x_ == other.x_) && (this.y_ == other.y_);
  }

  final int x_, y_;
}

class Line {
  const Line(Point begin, Point end)
      : beg_ = begin,
        end_ = end;
  final Point beg_;
  final Point end_;
}

class CTConstTest {
  static int getZero() {
    return 0;
  }

  static const naught = null;

  static testMain() {
    Expect.equals(0, Point.zero);
    Expect.equals(0, Point.origin.x_);
    Expect.equals(true, identical(Point.origin, Point.origin2));
    var p1 = const Point(0, 0);
    Expect.equals(true, identical(Point.origin, p1));

    Expect.equals(false, Point.origin == const Point(1, 1));
    Expect.equals(false, identical(Point.origin, const Point(1, 1)));

    var p2 = new Point(0, getZero());
    Expect.equals(true, Point.origin == p2); // Point.operator==

    Expect.equals(true, identical(const Point.X(5), const Point(5, 0)));
    Line l1 = const Line(Point.origin, const Point(1, 1));
    Line l2 = const Line(const Point(0, 0), const Point(1, 1));
    Line l3 = new Line(const Point(0, 0), const Point(1, 1));
    Expect.equals(true, identical(l1, l2));

    final evenNumbers = const <int>[2, 2 * 2, 2 * 3, 2 * 4, 2 * 5];
    Expect.equals(true, identical(evenNumbers, const <int>[2, 4, 6, 8, 10]));
    Expect.equals(
        true, !identical(evenNumbers, const <dynamic>[2, 4, 6, 8, 10]));

    final c11dGermany1 = const {"black": 1, "red": 2, "yellow": 3};
    Expect.equals(true,
        identical(c11dGermany1, const {"black": 1, "red": 2, "yellow": 3}));

    final c11dGermany2 = const {"black": 1, "red": 2, "yellow": 3};
    Expect.equals(true, identical(c11dGermany1, c11dGermany2));

    final c11dBelgium = const {"black": 1, "yellow": 2, "red": 3};
    Expect.equals(false, c11dGermany1 == c11dBelgium);
    Expect.equals(false, identical(c11dGermany1, c11dBelgium));

    final c11dItaly = const {"green": 1, "red": 3, "white": 2};
    Expect.equals(
        true, identical(c11dItaly, const {"green": 1, "red": 3, "white": 2}));
    Expect.equals(true, identical(c11dItaly, Roman.VivaItalia));

    Expect.equals(3, c11dItaly.length);
    Expect.equals(3, c11dItaly.keys.length);
    Expect.equals(true, c11dItaly.containsKey("white"));
    Expect.equals(false, c11dItaly.containsKey("black"));

    // Make sure the map object is immutable.
    bool caughtException = false;
    try {
      c11dItaly["green"] = 0;
    } on UnsupportedError catch (e) {
      caughtException = true;
    }
    Expect.equals(true, caughtException);
    Expect.equals(1, c11dItaly["green"]);

    caughtException = false;
    try {
      c11dItaly.clear();
    } on UnsupportedError catch (e) {
      caughtException = true;
    }
    Expect.equals(true, caughtException);
    Expect.equals(1, c11dItaly["green"]);

    caughtException = false;
    try {
      c11dItaly.remove("orange");
    } on UnsupportedError catch (e) {
      caughtException = true;
    }
    Expect.equals(true, caughtException);
    Expect.equals(1, c11dItaly["green"]);

    Expect.equals(true, null == naught);
  }
}

main() {
  CTConstTest.testMain();
}
