Files
sdk/runtime/vm/json_test.cc
T
Todd Turnidge b0ca0789be Fix a variety of service protocol bugs.
Add documentation for breakpoint.

Fix Instance.pattern documentation.

Fix Instance.bytes documentation.

Add class field for null instances.

Fix documentation of Context and closureContext.

Make getObject return Collected for deleted breakpoints.

Closes #24247
Closes #24249
Closes #24309
Closes #24325
Closes #24326
Closes #24327

BUG=
R=johnmccutchan@google.com

Review URL: https://codereview.chromium.org//1341473002 .
2015-09-11 12:29:21 -07:00

424 lines
11 KiB
C++

// 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.
#include "platform/assert.h"
#include "platform/json.h"
#include "vm/json_stream.h"
#include "vm/unit_test.h"
#include "vm/dart_api_impl.h"
namespace dart {
TEST_CASE(JSON_ScanJSON) {
const char* msg = "{ \"id\": 5, \"command\" : \"Debugger.pause\" }";
JSONScanner scanner(msg);
EXPECT_EQ(scanner.CurrentToken(), JSONScanner::TokenIllegal);
scanner.Scan();
EXPECT_EQ(scanner.CurrentToken(), JSONScanner::TokenLBrace);
scanner.Scan();
EXPECT_EQ(scanner.CurrentToken(), JSONScanner::TokenString);
EXPECT(scanner.IsStringLiteral("id"));
scanner.Scan();
EXPECT_EQ(scanner.CurrentToken(), JSONScanner::TokenColon);
scanner.Scan();
EXPECT_EQ(scanner.CurrentToken(), JSONScanner::TokenInteger);
scanner.Scan();
EXPECT_EQ(scanner.CurrentToken(), JSONScanner::TokenComma);
scanner.Scan();
EXPECT_EQ(scanner.CurrentToken(), JSONScanner::TokenString);
EXPECT(scanner.IsStringLiteral("command"));
scanner.Scan();
EXPECT_EQ(scanner.CurrentToken(), JSONScanner::TokenColon);
scanner.Scan();
EXPECT_EQ(scanner.CurrentToken(), JSONScanner::TokenString);
EXPECT(scanner.IsStringLiteral("Debugger.pause"));
scanner.Scan();
EXPECT_EQ(scanner.CurrentToken(), JSONScanner::TokenRBrace);
scanner.Scan();
EXPECT_EQ(scanner.CurrentToken(), JSONScanner::TokenEOM);
}
TEST_CASE(JSON_SyntaxError) {
const char* jobj = "{ \"id\": 5, "
" \"command\" : \"Debugger.stop\"" // Missing comma.
" \"params\" : { "
" \"url\" : \"blah.dart\", " // Missing comma.
" \"line\": 111, "
" },"
" \"foo\": \"outer foo\", "
"}";
JSONReader reader(jobj);
bool found;
found = reader.Seek("id");
EXPECT(found);
EXPECT_EQ(reader.Type(), JSONReader::kInteger);
found = reader.Seek("params");
EXPECT(!found);
EXPECT(reader.Error());
EXPECT_EQ(reader.Type(), JSONReader::kNone);
EXPECT_EQ(0, reader.ValueLen());
EXPECT(reader.ValueChars() == NULL);
}
TEST_CASE(JSON_JSONReader) {
const char* jobj = "{ \"id\": 5, "
" \"command\" : \"Debugger.setBreakpoint\","
" \"params\" : { "
" \"url\" : \"blah.dart\", "
" \"foo\" : [null, 1, { }, \"bar\", true, false],"
" \"line\": 111, "
" },"
" \"foo\": \"outer foo\", "
" \"quote\": \"\\\"\", "
" \"white\": \"\\t \\n\", "
"}";
JSONReader reader(jobj);
bool found;
char s[128];
found = reader.Seek("id");
EXPECT(found);
EXPECT_EQ(reader.Type(), JSONReader::kInteger);
found = reader.Seek("foo");
EXPECT(found);
EXPECT_EQ(reader.Type(), JSONReader::kString);
EXPECT(reader.IsStringLiteral("outer foo"));
found = reader.Seek("quote");
EXPECT(found);
EXPECT_EQ(reader.Type(), JSONReader::kString);
reader.GetRawValueChars(s, sizeof s);
EXPECT_STREQ("\\\"", s);
reader.GetDecodedValueChars(s, sizeof s);
EXPECT_STREQ("\"", s);
found = reader.Seek("white");
EXPECT(found);
EXPECT_EQ(reader.Type(), JSONReader::kString);
reader.GetRawValueChars(s, sizeof s);
EXPECT_STREQ("\\t \\n", s);
reader.GetDecodedValueChars(s, sizeof s);
EXPECT_STREQ("\t \n", s);
found = reader.Seek("line");
EXPECT(!found);
found = reader.Seek("params");
EXPECT(found);
EXPECT_EQ(reader.Type(), JSONReader::kObject);
reader.Set(reader.ValueChars());
found = reader.Seek("foo");
EXPECT(found);
EXPECT_EQ(reader.Type(), JSONReader::kArray);
found = reader.Seek("non-existing");
EXPECT(!found);
found = reader.Seek("line");
EXPECT(found);
EXPECT_EQ(reader.Type(), JSONReader::kInteger);
}
TEST_CASE(JSON_TextBuffer) {
TextBuffer w(5); // Small enough to make buffer grow at least once.
w.Printf("{ \"%s\" : %d", "length", 175);
EXPECT_STREQ("{ \"length\" : 175", w.buf());
w.Printf(", \"%s\" : \"%s\" }", "command", "stopIt");
EXPECT_STREQ("{ \"length\" : 175, \"command\" : \"stopIt\" }", w.buf());
JSONReader r(w.buf());
bool found = r.Seek("command");
EXPECT(found);
EXPECT_EQ(r.Type(), JSONReader::kString);
EXPECT(r.IsStringLiteral("stopIt"));
}
TEST_CASE(JSON_JSONStream_Primitives) {
{
JSONStream js;
{
JSONObject jsobj(&js);
}
EXPECT_STREQ("{}", js.ToCString());
}
{
JSONStream js;
{
JSONArray jsarr(&js);
}
EXPECT_STREQ("[]", js.ToCString());
}
{
JSONStream js;
{
JSONArray jsarr(&js);
jsarr.AddValue(true);
}
EXPECT_STREQ("[true]", js.ToCString());
}
{
JSONStream js;
{
JSONArray jsarr(&js);
jsarr.AddValue(false);
}
EXPECT_STREQ("[false]", js.ToCString());
}
{
JSONStream js;
{
JSONArray jsarr(&js);
jsarr.AddValue(static_cast<intptr_t>(4));
}
EXPECT_STREQ("[4]", js.ToCString());
}
{
JSONStream js;
{
JSONArray jsarr(&js);
jsarr.AddValue(1.0);
}
EXPECT_STREQ("[1.000000]", js.ToCString());
}
{
JSONStream js;
{
JSONArray jsarr(&js);
jsarr.AddValue("hello");
}
EXPECT_STREQ("[\"hello\"]", js.ToCString());
}
{
JSONStream js;
{
JSONArray jsarr(&js);
jsarr.AddValueF("h%s", "elo");
}
EXPECT_STREQ("[\"helo\"]", js.ToCString());
}
}
TEST_CASE(JSON_JSONStream_Array) {
JSONStream js;
{
JSONArray jsarr(&js);
jsarr.AddValue(true);
jsarr.AddValue(false);
}
EXPECT_STREQ("[true,false]", js.ToCString());
}
TEST_CASE(JSON_JSONStream_Object) {
JSONStream js;
{
JSONObject jsobj(&js);
jsobj.AddProperty("key1", "a");
jsobj.AddProperty("key2", "b");
}
EXPECT_STREQ("{\"key1\":\"a\",\"key2\":\"b\"}", js.ToCString());
}
TEST_CASE(JSON_JSONStream_NestedObject) {
JSONStream js;
{
JSONObject jsobj(&js);
JSONObject jsobj1(&jsobj, "key");
jsobj1.AddProperty("key1", "d");
}
EXPECT_STREQ("{\"key\":{\"key1\":\"d\"}}", js.ToCString());
}
TEST_CASE(JSON_JSONStream_ObjectArray) {
JSONStream js;
{
JSONArray jsarr(&js);
{
JSONObject jsobj(&jsarr);
jsobj.AddProperty("key", "e");
}
{
JSONObject jsobj(&jsarr);
jsobj.AddProperty("yek", "f");
}
}
EXPECT_STREQ("[{\"key\":\"e\"},{\"yek\":\"f\"}]", js.ToCString());
}
TEST_CASE(JSON_JSONStream_ArrayArray) {
JSONStream js;
{
JSONArray jsarr(&js);
{
JSONArray jsarr1(&jsarr);
jsarr1.AddValue(static_cast<intptr_t>(4));
}
{
JSONArray jsarr1(&jsarr);
jsarr1.AddValue(false);
}
}
EXPECT_STREQ("[[4],[false]]", js.ToCString());
}
TEST_CASE(JSON_JSONStream_Printf) {
JSONStream js;
{
JSONArray jsarr(&js);
jsarr.AddValueF("%d %s", 2, "hello");
}
EXPECT_STREQ("[\"2 hello\"]", js.ToCString());
}
TEST_CASE(JSON_JSONStream_ObjectPrintf) {
JSONStream js;
{
JSONObject jsobj(&js);
jsobj.AddPropertyF("key", "%d %s", 2, "hello");
}
EXPECT_STREQ("{\"key\":\"2 hello\"}", js.ToCString());
}
TEST_CASE(JSON_JSONStream_DartObject) {
JSONStream js;
{
JSONArray jsarr(&js);
jsarr.AddValue(Object::Handle(Object::null()));
JSONObject jsobj(&jsarr);
jsobj.AddProperty("object_key", Object::Handle(Object::null()));
}
char buffer[1024];
ElideJSONSubstring("classes", js.ToCString(), buffer);
EXPECT_STREQ("[{\"type\":\"@Instance\","
"\"_vmType\":\"null\","
"\"class\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
"\"name\":\"Null\"},"
"\"kind\":\"Null\","
"\"fixedId\":true,"
"\"id\":\"objects\\/null\","
"\"valueAsString\":\"null\"},"
"{\"object_key\":"
"{\"type\":\"@Instance\","
"\"_vmType\":\"null\","
"\"class\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
"\"name\":\"Null\"},"
"\"kind\":\"Null\","
"\"fixedId\":true,"
"\"id\":\"objects\\/null\","
"\"valueAsString\":\"null\"}}]",
buffer);
}
TEST_CASE(JSON_JSONStream_EscapedString) {
JSONStream js;
{
JSONArray jsarr(&js);
jsarr.AddValue("Hel\"\"lo\r\n\t");
}
EXPECT_STREQ("[\"Hel\\\"\\\"lo\\r\\n\\t\"]", js.ToCString());
}
TEST_CASE(JSON_JSONStream_DartString) {
const char* kScriptChars =
"var ascii = 'Hello, World!';\n"
"var unicode = '\\u00CE\\u00F1\\u0163\\u00E9r\\u00F1\\u00E5\\u0163"
"\\u00EE\\u00F6\\u00F1\\u00E5\\u013C\\u00EE\\u017E\\u00E5\\u0163"
"\\u00EE\\u1EDD\\u00F1';\n"
"var surrogates = '\\u{1D11E}\\u{1D11E}\\u{1D11E}\\u{1D11E}"
"\\u{1D11E}';\n"
"var nullInMiddle = 'This has\\u0000 four words.';";
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
EXPECT_VALID(lib);
Dart_Handle result;
String& obj = String::Handle();
{
result = Dart_GetField(lib, NewString("ascii"));
EXPECT_VALID(result);
obj ^= Api::UnwrapHandle(result);
JSONStream js;
{
JSONObject jsobj(&js);
jsobj.AddPropertyStr("ascci", obj);;
}
EXPECT_STREQ("{\"ascci\":\"Hello, World!\"}", js.ToCString());
}
{
result = Dart_GetField(lib, NewString("unicode"));
EXPECT_VALID(result);
obj ^= Api::UnwrapHandle(result);
JSONStream js;
{
JSONObject jsobj(&js);
jsobj.AddPropertyStr("unicode", obj);
}
EXPECT_STREQ("{\"unicode\":\"\\u00CE\\u00F1\\u0163\\u00E9r\\u00F1\\u00E5"
"\\u0163\\u00EE\\u00F6\\u00F1\\u00E5\\u013C\\u00EE\\u017E"
"\\u00E5\\u0163\\u00EE\\u1EDD\\u00F1\"}", js.ToCString());
}
{
result = Dart_GetField(lib, NewString("surrogates"));
EXPECT_VALID(result);
obj ^= Api::UnwrapHandle(result);
JSONStream js;
{
JSONObject jsobj(&js);
jsobj.AddPropertyStr("surrogates", obj);
}
EXPECT_STREQ("{\"surrogates\":\"\\uD834\\uDD1E\\uD834\\uDD1E\\uD834\\uDD1E"
"\\uD834\\uDD1E\\uD834\\uDD1E\"}", js.ToCString());
}
{
result = Dart_GetField(lib, NewString("nullInMiddle"));
EXPECT_VALID(result);
obj ^= Api::UnwrapHandle(result);
JSONStream js;
{
JSONObject jsobj(&js);
jsobj.AddPropertyStr("nullInMiddle", obj);
}
EXPECT_STREQ("{\"nullInMiddle\":\"This has\\u0000 four words.\"}",
js.ToCString());
}
}
TEST_CASE(JSON_JSONStream_Params) {
const char* param_keys[] = {"dog", "cat"};
const char* param_values[] = {"apple", "banana"};
JSONStream js;
EXPECT(js.num_params() == 0);
js.SetParams(&param_keys[0], &param_values[0], 2);
EXPECT(js.num_params() == 2);
EXPECT(!js.HasParam("lizard"));
EXPECT(js.HasParam("dog"));
EXPECT(js.HasParam("cat"));
EXPECT(js.ParamIs("cat", "banana"));
EXPECT(!js.ParamIs("dog", "banana"));
}
} // namespace dart