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

// @dart = 2.9

import 'package:expect/expect.dart';
import 'dart:convert';

main() {
  testParsing();
  testStringify();
  testStringifyErrors();
}

void testParsing() {
  // Scalars.
  Expect.equals(5, json.decode(' 5 '));
  Expect.equals(-42, json.decode(' -42 '));
  Expect.equals(3, json.decode(' 3e0 '));
  Expect.equals(3.14, json.decode(' 3.14 '));
  Expect.isTrue(json.decode('true '));
  Expect.isFalse(json.decode(' false'));
  Expect.isNull(json.decode(' null '));
  Expect.isNull(json.decode('\n\rnull\t'));
  Expect.equals('hi there" bob', json.decode(' "hi there\\" bob" '));
  Expect.equals('', json.decode(' "" '));

  // Lists.
  Expect.deepEquals([], json.decode(' [] '));
  Expect.deepEquals([], json.decode('[ ]'));
  Expect.deepEquals([3, -4.5, true, 'hi', false],
      json.decode(' [3, -4.5, true, "hi", false] '));
  // Nulls are tricky.
  Expect.deepEquals([null], json.decode('[null]'));
  Expect.deepEquals([3, -4.5, null, true, 'hi', false],
      json.decode(' [3, -4.5, null, true, "hi", false] '));
  Expect.deepEquals([
    [null]
  ], json.decode('[[null]]'));
  Expect.deepEquals([
    [3],
    [],
    [null],
    ['hi', true]
  ], json.decode(' [ [3], [], [null], ["hi", true]] '));

  // Maps.
  Expect.deepEquals({}, json.decode(' {} '));
  Expect.deepEquals({}, json.decode('{ }'));

  Expect.deepEquals({"x": 3, "y": -4.5, "z": "hi", "u": true, "v": false},
      json.decode(' {"x":3, "y": -4.5,  "z" : "hi","u" : true, "v": false } '));

  Expect.deepEquals({"x": 3, "y": -4.5, "z": "hi"},
      json.decode(' {"x":3, "y": -4.5,  "z" : "hi" } '));

  Expect.deepEquals({"y": -4.5, "z": "hi", "x": 3},
      json.decode(' {"y": -4.5,  "z" : "hi" ,"x":3 } '));

  Expect.deepEquals(
      {" hi bob ": 3, "": 4.5}, json.decode('{ " hi bob " :3, "": 4.5}'));

  Expect.deepEquals({'x': {}}, json.decode(' { "x" : { } } '));
  Expect.deepEquals({'x': {}}, json.decode('{"x":{}}'));

  // Nulls are tricky.
  Expect.deepEquals({'w': null}, json.decode('{"w":null}'));

  Expect.deepEquals({
    "x": {"w": null}
  }, json.decode('{"x":{"w":null}}'));

  Expect.deepEquals(
      {"x": 3, "y": -4.5, "z": "hi", "w": null, "u": true, "v": false},
      json.decode(' {"x":3, "y": -4.5,  "z" : "hi",'
          '"w":null, "u" : true, "v": false } '));

  Expect.deepEquals(
      {
        "x": {"a": 3, "b": -4.5},
        "y": [{}],
        "z": "hi",
        "w": {"c": null, "d": true},
        "v": null
      },
      json.decode('{"x": {"a":3, "b": -4.5}, "y":[{}], '
          '"z":"hi","w":{"c":null,"d":true}, "v":null}'));
}

void testStringify() {
  // Scalars.
  Expect.equals('5', json.encode(5));
  Expect.equals('-42', json.encode(-42));
  // Dart does not guarantee a formatting for doubles,
  // so reparse and compare to the original.
  validateRoundTrip(3.14);
  Expect.equals('true', json.encode(true));
  Expect.equals('false', json.encode(false));
  Expect.equals('null', json.encode(null));
  Expect.equals('" hi there\\" bob "', json.encode(' hi there" bob '));
  Expect.equals('"hi\\\\there"', json.encode('hi\\there'));
  Expect.equals('"hi\\nthere"', json.encode('hi\nthere'));
  Expect.equals('"hi\\r\\nthere"', json.encode('hi\r\nthere'));
  Expect.equals('""', json.encode(''));

  // Lists.
  Expect.equals('[]', json.encode([]));
  Expect.equals('[]', json.encode(new List(0)));
  Expect.equals('[null,null,null]', json.encode(new List(3)));
  validateRoundTrip([3, -4.5, null, true, 'hi', false]);
  Expect.equals(
      '[[3],[],[null],["hi",true]]',
      json.encode([
        [3],
        [],
        [null],
        ['hi', true]
      ]));

  // Maps.
  Expect.equals('{}', json.encode({}));
  Expect.equals('{}', json.encode(new Map()));
  Expect.equals('{"x":{}}', json.encode({'x': {}}));
  Expect.equals(
      '{"x":{"a":3}}',
      json.encode({
        'x': {'a': 3}
      }));

  // Dart does not guarantee an order on the keys
  // of a map literal, so reparse and compare to the original Map.
  validateRoundTrip(
      {'x': 3, 'y': -4.5, 'z': 'hi', 'w': null, 'u': true, 'v': false});
  validateRoundTrip({"x": 3, "y": -4.5, "z": 'hi'});
  validateRoundTrip({' hi bob ': 3, '': 4.5});
  validateRoundTrip({
    'x': {'a': 3, 'b': -4.5},
    'y': [{}],
    'z': 'hi',
    'w': {'c': null, 'd': true},
    'v': null
  });

  Expect.equals("4", json.encode(new ToJson(4)));
  Expect.equals('[4,"a"]', json.encode(new ToJson([4, "a"])));
  Expect.equals(
      '[4,{"x":42}]',
      json.encode(new ToJson([
        4,
        new ToJson({"x": 42})
      ])));

  expectThrowsJsonError(() => json.encode([new ToJson(new ToJson(4))]));
  expectThrowsJsonError(() => json.encode([new Object()]));
}

void testStringifyErrors() {
  // Throws if argument cannot be converted.
  expectThrowsJsonError(() => json.encode(new TestClass()));

  // Throws if toJson throws.
  expectThrowsJsonError(() => json.encode(new ToJsoner("bad", throws: true)));

  // Throws if toJson returns non-serializable value.
  expectThrowsJsonError(() => json.encode(new ToJsoner(new TestClass())));

  // Throws on cyclic values.
  var a = [];
  var b = a;
  for (int i = 0; i < 50; i++) {
    b = [b];
  }
  a.add(b);
  expectThrowsJsonError(() => json.encode(a));
}

void expectThrowsJsonError(void f()) {
  Expect.throws(f, (e) => e is JsonUnsupportedObjectError);
}

class TestClass {
  int x;
  String y;

  TestClass()
      : x = 3,
        y = 'joe' {}
}

class ToJsoner {
  final Object returnValue;
  final bool throws;
  ToJsoner(this.returnValue, {this.throws});
  Object toJson() {
    if (throws) throw returnValue;
    return returnValue;
  }
}

class ToJson {
  final object;
  const ToJson(this.object);
  toJson() => object;
}

/**
 * Checks that the argument can be converted to a JSON string and
 * back, and produce something equivalent to the argument.
 */
validateRoundTrip(expected) {
  Expect.deepEquals(expected, json.decode(json.encode(expected)));
}
