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

library json_test;

import "dart:json";

bool badFormat(e) => e is FormatException;

void testJson(json, expected) {
  var value = parse(json);
  compare(expected, actual, path) {
    if (expected is List) {
      Expect.isTrue(actual is List);
      Expect.equals(expected.length, actual.length, "$path: List length");
      for (int i = 0; i < expected.length; i++) {
        compare(expected[i], actual[i], "$path[$i]");
      }
    } else if (expected is Map) {
      Expect.isTrue(actual is Map);
      Expect.equals(expected.length, actual.length, "$path: Map size");
      expected.forEach((key, value) {
        Expect.isTrue(actual.containsKey(key));
        compare(value, actual[key], "$path[$key]");
      });
    } else if (expected is num) {
      Expect.equals(expected is int, actual is int, "$path: same number type");
      Expect.isTrue(expected.compareTo(actual) == 0,
                    "$path: $expected vs. $actual");
    } else {
      // String, bool, null.
      Expect.equals(expected, actual, path);
    }
  }
  compare(expected, value, "value");
}

String escape(String s) {
  var sb = new StringBuffer();
  for (int i = 0; i < s.length; i++) {
    int code = s.codeUnitAt(i);
    if (code == '\\'.codeUnitAt(0)) sb.write(r'\\');
    else if (code == '\"'.codeUnitAt(0)) sb.write(r'\"');
    else if (code >= 32 && code < 127) sb.writeCharCode(code);
    else {
      String hex = '000${code.toRadixString(16)}';
      sb.write(r'\u' '${hex.substring(hex.length - 4)}');
    }
  }
  return '$sb';
}

void testThrows(json) {
  Expect.throws(() => parse(json), badFormat, "json = '${escape(json)}'");
}

testNumbers() {
  // Positive tests for number formats.
  var integerList = ["0","9","9999"];
  var signList = ["", "-"];
  var fractionList = ["", ".0", ".1", ".99999"];
  var exponentList = [""];
  for (var exphead in ["e", "E", "e-", "E-", "e+", "E+"]) {
    for (var expval in ["0", "1", "200"]) {
      exponentList.add("$exphead$expval");
    }
  }

  for (var integer in integerList) {
    for (var sign in signList) {
      for (var fraction in fractionList) {
        for (var exp in exponentList) {
          var literal = "$sign$integer$fraction$exp";
          var parseNumber =
              ((fraction == "" && exp == "") ? (String x) => int.parse(x)
                                             : (String x) => double.parse(x));
          var expectedValue = parseNumber(literal);
          testJson(literal, expectedValue);
        }
      }
    }
  }

  // Negative tests (syntax error).
  // testError thoroughly tests the given parts with a lot of valid
  // values for the other parts.
  testError({signs, integers, fractions, exponents}) {
    def(value, defaultValue) {
      if (value == null) return defaultValue;
      if (value is List) return value;
      return [value];
    }
    signs = def(signs, signList);
    integers = def(integers, integerList);
    fractions = def(fractions, fractionList);
    exponents = def(exponents, exponentList);
    for (var integer in integers) {
      for (var sign in signs) {
        for (var fraction in fractions) {
          for (var exponent in exponents) {
            var literal = "$sign$integer$fraction$exponent";
            testThrows(literal);
          }
        }
      }
    }
  }
  // Doubles overflow to Infinity.
  testJson("1e+400", double.INFINITY);
  // (Integers do not, but we don't have those on dart2js).

  // Integer part cannot be omitted:
  testError(integers: "");

  // Test for "Initial zero only allowed for zero integer part" moved to
  // json_strict_test.dart because IE's JSON.parse accepts additional initial
  // zeros.

  // Only minus allowed as sign.
  testError(signs: "+");
  // Requires digits after decimal point.
  testError(fractions: ".");
  // Requires exponent digts, and only digits.
  testError(exponents: ["e", "e+", "e-", "e.0"]);

  // No whitespace inside numbers.
  // Additional case "- 2.2e+2" in json_strict_test.dart.
  testThrows("-2 .2e+2");
  testThrows("-2. 2e+2");
  testThrows("-2.2 e+2");
  testThrows("-2.2e +2");
  testThrows("-2.2e+ 2");

  testThrows("[2.,2]");
  testThrows("{2.:2}");
}

testStrings() {
  // String parser accepts and understands escapes.
  var input = r'"\u0000\uffff\n\r\f\t\b\/\\\"' '\x20\ufffd\uffff"';
  var expected = "\u0000\uffff\n\r\f\t\b\/\\\"\x20\ufffd\uffff";
  testJson(input, expected);
  // Empty string.
  testJson(r'""', "");
  // Escape first.
  testJson(r'"\"........"', "\"........");
  // Escape last.
  testJson(r'"........\""', "........\"");
  // Escape middle.
  testJson(r'"....\"...."', "....\"....");

  // Does not accept single quotes.
  testThrows(r"''");
  // Throws on unterminated strings.
  testThrows(r'"......\"');
  // Throws on unterminated escapes.
  testThrows(r'"\');  // ' is not escaped.
  testThrows(r'"\a"');
  testThrows(r'"\u"');
  testThrows(r'"\u1"');
  testThrows(r'"\u12"');
  testThrows(r'"\u123"');
  testThrows(r'"\ux"');
  testThrows(r'"\u1x"');
  testThrows(r'"\u12x"');
  testThrows(r'"\u123x"');
  // Throws on bad escapes.
  testThrows(r'"\a"');
  testThrows(r'"\x00"');
  testThrows(r'"\c2"');
  testThrows(r'"\000"');
  testThrows(r'"\u{0}"');
  testThrows(r'"\%"');
  testThrows('"\\\x00"'); // Not raw string!
  // Throws on control characters.
  for (int i = 0; i < 32; i++) {
    var string = new String.fromCharCodes([0x22,i,0x22]); // '"\x00"' etc.
    testThrows(string);
  }
}


testObjects() {
  testJson(r'{}', {});
  testJson(r'{"x":42}', {"x":42});
  testJson(r'{"x":{"x":{"x":42}}}', {"x": {"x": {"x": 42}}});
  testJson(r'{"x":10,"x":42}', {"x": 42});
  testJson(r'{"":42}', {"": 42});

  // Keys must be strings.
  testThrows(r'{x:10}');
  testThrows(r'{true:10}');
  testThrows(r'{false:10}');
  testThrows(r'{null:10}');
  testThrows(r'{42:10}');
  testThrows(r'{42e1:10}');
  testThrows(r'{-42:10}');
  testThrows(r'{["text"]:10}');
  testThrows(r'{:10}');
}

testArrays() {
  testJson(r'[]', []);
  testJson(r'[1.1e1,"string",true,false,null,{}]',
           [1.1e1, "string", true, false, null, {}]);
  testJson(r'[[[[[[]]]],[[[]]],[[]]]]', [[[[[[]]]],[[[]]],[[]]]]);
  testJson(r'[{},[{}],{"x":[]}]', [{},[{}],{"x":[]}]);

  testThrows(r'[1,,2]');
  testThrows(r'[1,2,]');
  testThrows(r'[,2]');
}

testWords() {
  testJson(r'true', true);
  testJson(r'false', false);
  testJson(r'null', null);
  testJson(r'[true]', [true]);
  testJson(r'{"true":true}', {"true": true});

  testThrows(r'truefalse');
  testThrows(r'trues');
  testThrows(r'nulll');
  testThrows(r'full');
  testThrows(r'nul');
  testThrows(r'tru');
  testThrows(r'fals');
  testThrows(r'\null');
  testThrows(r't\rue');
  testThrows(r't\rue');
}

testWhitespace() {
  // Valid white-space characters.
  var v = '\t\r\n\ ';
  // Invalid white-space and non-recognized characters.
  var invalids = ['\x00', '\f', '\x08', '\\', '\xa0','\u2028', '\u2029'];

  // Valid whitespace accepted "everywhere".
  testJson('$v[${v}-2.2e2$v,$v{$v"key"$v:${v}true$v}$v,$v"ab"$v]$v',
           [-2.2e2, {"key": true}, "ab"]);

  // IE9 accepts invalid characters at the end, so some of these tests have been
  // moved to json_strict_test.dart.
  for (var i in invalids) {
    testThrows('${i}"s"');
    testThrows('42${i}');
    testThrows('$i[]');
    testThrows('[$i]');
    testThrows('[$i"s"]');
    testThrows('["s"$i]');
    testThrows('$i{"k":"v"}');
    testThrows('{$i"k":"v"}');
    testThrows('{"k"$i:"v"}');
    testThrows('{"k":$i"v"}');
    testThrows('{"k":"v"$i}');
  }
}

main() {
  testNumbers();
  testStrings();
  testWords();
  testObjects();
  testArrays();
  testWhitespace();
}
