// 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";

// Tests all statement types. Not an exhaustive test of all statement semantics.
class StatementTest {

  StatementTest() {}

  static testMain() {
    var test = new StatementTest();
    test.testIfStatement();
    test.testForLoop();
    test.testWhileLoops();
    test.testSwitch();
    test.testExceptions();
    test.testBreak();
    test.testContinue();
    test.testFunction();
    test.testReturn();
  }

  testIfStatement() {
    // Basic if statements.
    if (true) {
      Expect.equals(true, true);
    } else {
      Expect.equals(false, true);
    }

    if (false) {
      Expect.equals(false, true);
    } else {
      Expect.equals(true, true);
    }
  }

  testForLoop() {
    int count = 0, count2;

    // Basic for loop.
    for (int i = 0; i < 10; ++i) {
      ++count;
    }
    Expect.equals(10, count);

    // For loop with no 'var'.
    count2 = 0;
    for (count = 0; count < 5; ++count) {
      ++count2;
    }
    Expect.equals(5, count);
    Expect.equals(5, count2);

    // For loop with no initializer.
    count = count2 = 0;
    for (; count < 10; ++count) {
      ++count2;
    }
    Expect.equals(10, count);
    Expect.equals(10, count2);

    // For loop with no increment.
    for (count = 0; count < 5; ) {
      ++count;
    }
    Expect.equals(5, count);

    // For loop with no test.
    for (count = 0; ; ++count) {
      if (count == 10) {
        break;
      }
    }
    Expect.equals(10, count);

    // For loop with no nothing.
    count = 0;
    for (;;) {
      if (count == 5) {
        break;
      }
      ++count;
    }
    Expect.equals(5, count);
  }

  testWhileLoops() {
    // Basic while loop.
    int count = 0;
    while (count < 10) {
      ++count;
    }
    Expect.equals(10, count);

    // Basic do loop.
    count = 0;
    do {
      ++count;
    } while (count < 5);
    Expect.equals(5, count);
  }

  testSwitch() {
    // Int switch.
    bool hit0, hit1, hitDefault;
    for (int x = 0; x < 3; ++x) {
      switch (x) {
        case 0:  hit0 = true;       break;
        case 1:  hit1 = true;       break;
        default: hitDefault = true; break;
      }
    }
    Expect.equals(true, hit0);
    Expect.equals(true, hit1);
    Expect.equals(true, hitDefault);

    // String switch.
    var strings = ['a', 'b', 'c'];
    bool hitA, hitB;
    hitDefault = false;
    for (int x = 0; x < 3; ++x) {
      switch (strings[x]) {
        case 'a': hitA = true;       break;
        case 'b': hitB = true;       break;
        default:  hitDefault = true; break;
      }
    }
    Expect.equals(true, hitA);
    Expect.equals(true, hitB);
    Expect.equals(true, hitDefault);
  }

  testExceptions() {
    // TODO(jgw): Better tests once all the exception semantics are worked out.
    bool hitCatch, hitFinally;
    try {
      throw "foo";
    } catch (e) {
      Expect.equals(true, e == "foo");
      hitCatch = true;
    } finally {
      hitFinally = true;
    }

    Expect.equals(true, hitCatch);
    Expect.equals(true, hitFinally);
  }

  testBreak() {
    var ints = [
      [ 32, 87, 3, 589 ],
      [ 12, 1076, 2000, 8 ],
      [ 622, 127, 77, 955 ]
    ];
    int i, j = 0;
    bool foundIt = false;

  search:
    for (i = 0; i < ints.length; i++) {
      for (j = 0; j < ints[i].length; j++) {
        if (ints[i][j] == 12) {
          foundIt = true;
          break search;
        }
      }
    }
    Expect.equals(true, foundIt);
  }

  testContinue() {
    String searchMe = "Look for a substring in me";
    String substring = "sub";
    bool foundIt = false;
    int max = searchMe.length - substring.length;

  test:
    for (int i = 0; i <= max; i++) {
      int n = substring.length;
      int j = i;
      int k = 0;
      while (n-- != 0) {
        if (searchMe[j++] != substring[k++]) {
          continue test;
        }
      }
      foundIt = true;
      break test;
    }
  }

  testFunction() {
    int foo() {
      return 42;
    }
    Expect.equals(42, foo());
  }

  void testReturn() {
    if (true) {
      return;
    }
    Expect.equals(true, false);
  }
}

main() {
  StatementTest.testMain();
}
