// 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.

import "package:expect/expect.dart";

class ExpandoTest {
  static Expando<int> visits;

  static testMain() {
    visits = new Expando<int>('visits');
    var legal = [ new Object(),
                  new List(), [1,2,3], const [1,2,3],
                  new Map(), {'x':1,'y':2}, const {'x':1,'y':2},
                  new Expando(), new Expando('horse') ];
    for (var object in legal) {
      testNamedExpando(object);
      testUnnamedExpando(object);
    }
    for (var object in legal) {
      Expect.equals(2, visits[object]);
    }
    testIllegal();
  }

  static visit(object) {
    int count = visits[object];
    count = (count == null) ? 1 : count + 1;
    visits[object] = count;
  }

  static testNamedExpando(object) {
    Expando<int> expando = new Expando<int>('myexpando');
    Expect.equals('myexpando', expando.name);
    Expect.isTrue(expando.toString().startsWith('Expando:myexpando'));
    testExpando(expando, object);
  }

  static testUnnamedExpando(object) {
    Expando<int> expando = new Expando<int>();
    Expect.isNull(expando.name);
    Expect.isTrue(expando.toString().startsWith('Expando:'));
    testExpando(expando, object);
  }

  static testExpando(Expando<int> expando, object) {
    visit(object);

    Expect.isNull(expando[object]);
    expando[object] = 42;
    Expect.equals(42, expando[object]);
    expando[object] = null;
    Expect.isNull(expando[object]);

    Expando<int> alternative = new Expando('myexpando');
    Expect.isNull(alternative[object]);
    alternative[object] = 87;
    Expect.isNull(expando[object]);
    expando[object] = 99;
    Expect.equals(99, expando[object]);
    Expect.equals(87, alternative[object]);
  }

  static testIllegal() {
    Expando<int> expando = new Expando<int>();
    Expect.throws(() => expando[null], (exception)
                  => exception is ArgumentError);
    Expect.throws(() => expando['string'], (exception)
                  => exception is ArgumentError);
    Expect.throws(() => expando['string'], (exception)
                  => exception is ArgumentError);
    Expect.throws(() => expando[42], (exception)
                  => exception is ArgumentError);
    Expect.throws(() => expando[42.87], (exception)
                  => exception is ArgumentError);
    Expect.throws(() => expando[true], (exception)
                  => exception is ArgumentError);
    Expect.throws(() => expando[false], (exception)
                  => exception is ArgumentError);
  }
}

main() => ExpandoTest.testMain();
