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