Commit 40eb4427 authored by Mathias Bynens's avatar Mathias Bynens Committed by Commit Bot

[test] Fix expectations in WebKit JSON.stringify tests

The reference implementation used in the tests does not fully match
the spec, so for the diverging cases we need to explicitly specify
the correct expectation.

Every single change in this patch has been verified against every
major JavaScript engine using eshost + jsvu. All implementations
match the spec (and the V8 implementation), with the following two
exceptions:

- One expectation was wrong because of a JavaScriptCore bug (that
  is, we inherited the incorrect expectation when importing the
  tests from WebKit). A comment was added for that one.
- This work resulted in the discovery of bugs in Moddable/XS:
  https://github.com/Moddable-OpenSource/moddable/issues/112

Change-Id: I05d91d7acc5c8765e941fcd68c1086c2694c710c
Reviewed-on: https://chromium-review.googlesource.com/c/1396081Reviewed-by: 's avatarSigurd Schneider <sigurds@chromium.org>
Commit-Queue: Mathias Bynens <mathias@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58546}
parent af0428ac
...@@ -88,10 +88,10 @@ function createTests() { ...@@ -88,10 +88,10 @@ function createTests() {
result[result.length - 1].expected = '2'; result[result.length - 1].expected = '2';
result.push(function (jsonObject){ result.push(function (jsonObject){
var value = new Boolean(true); var value = new Boolean(true);
value.valueOf = function() { return 2; }; value.valueOf = function() { return false; };
return jsonObject.stringify(value); return jsonObject.stringify(value);
}); });
result[result.length - 1].expected = '2'; result[result.length - 1].expected = 'true';
result.push(function (jsonObject){ result.push(function (jsonObject){
var value = new String("fail"); var value = new String("fail");
value.toString = function() { return "converted string"; }; value.toString = function() { return "converted string"; };
...@@ -114,10 +114,13 @@ function createTests() { ...@@ -114,10 +114,13 @@ function createTests() {
result.push(function (jsonObject){ result.push(function (jsonObject){
return jsonObject.stringify({toJSON: Date.prototype.toJSON, toISOString: function(){ return "custom toISOString"; }}); return jsonObject.stringify({toJSON: Date.prototype.toJSON, toISOString: function(){ return "custom toISOString"; }});
}); });
// Note: JSC fails the following test. Every other engine matches the spec.
// This is also covered by the test in
// https://github.com/v8/v8/blob/fc664bda1725de0412f6d197fda9503d6e6e122e/test/mjsunit/json.js#L78-L80
result.push(function (jsonObject){ result.push(function (jsonObject){
return jsonObject.stringify({toJSON: Date.prototype.toJSON, toISOString: function(){ return {}; }}); return jsonObject.stringify({toJSON: Date.prototype.toJSON, toISOString: function(){ return {}; }});
}); });
result[result.length - 1].throws = true; result[result.length - 1].expected = '{}';
result.push(function (jsonObject){ result.push(function (jsonObject){
return jsonObject.stringify({toJSON: Date.prototype.toJSON, toISOString: function(){ throw "An exception"; }}); return jsonObject.stringify({toJSON: Date.prototype.toJSON, toISOString: function(){ throw "An exception"; }});
}); });
...@@ -162,6 +165,7 @@ function createTests() { ...@@ -162,6 +165,7 @@ function createTests() {
jsonObject.stringify([1,2,3,4,5], function(k,v){allString = allString && (typeof k == "string"); return v}); jsonObject.stringify([1,2,3,4,5], function(k,v){allString = allString && (typeof k == "string"); return v});
return allString; return allString;
}); });
result[result.length - 1].expected = true;
result.push(function (jsonObject){ result.push(function (jsonObject){
var allString = true; var allString = true;
var array = []; var array = [];
...@@ -332,9 +336,11 @@ function createTests() { ...@@ -332,9 +336,11 @@ function createTests() {
result.push(function (jsonObject){ result.push(function (jsonObject){
return jsonObject.stringify(objectWithSideEffectGetter); return jsonObject.stringify(objectWithSideEffectGetter);
}); });
result[result.length - 1].expected = '{}';
result.push(function (jsonObject){ result.push(function (jsonObject){
return jsonObject.stringify(objectWithSideEffectGetterAndProto); return jsonObject.stringify(objectWithSideEffectGetterAndProto);
}); });
result[result.length - 1].expected = '{}';
result.push(function (jsonObject){ result.push(function (jsonObject){
return jsonObject.stringify(arrayWithSideEffectGetter); return jsonObject.stringify(arrayWithSideEffectGetter);
}); });
...@@ -351,7 +357,7 @@ function createTests() { ...@@ -351,7 +357,7 @@ function createTests() {
jsonObject.stringify([1,2,3,,,,4,5,6], replaceFunc); jsonObject.stringify([1,2,3,,,,4,5,6], replaceFunc);
return replaceTracker; return replaceTracker;
}); });
result[result.length - 1].expected = '(string)[1,2,3,null,null,null,4,5,6];0(number)1;1(number)2;2(number)3;3(number)undefined;4(number)undefined;5(number)undefined;6(number)4;7(number)5;8(number)6;' result[result.length - 1].expected = '(string)[1,2,3,null,null,null,4,5,6];0(string)1;1(string)2;2(string)3;3(string)undefined;4(string)undefined;5(string)undefined;6(string)4;7(string)5;8(string)6;';
result.push(function (jsonObject){ result.push(function (jsonObject){
replaceTracker = ""; replaceTracker = "";
jsonObject.stringify({a:"a", b:"b", c:"c", 3: "d", 2: "e", 1: "f"}, replaceFunc); jsonObject.stringify({a:"a", b:"b", c:"c", 3: "d", 2: "e", 1: "f"}, replaceFunc);
...@@ -432,7 +438,7 @@ function createTests() { ...@@ -432,7 +438,7 @@ function createTests() {
try { jsonObject.stringify(cyclicArray); } catch { cycleTracker += " -> exception" } try { jsonObject.stringify(cyclicArray); } catch { cycleTracker += " -> exception" }
return cycleTracker; return cycleTracker;
}); });
result[result.length - 1].expected = "0(number):[object Object]first, -> exception"; result[result.length - 1].expected = "0(string):[object Object]first, -> exception";
function createArray(len, o) { var r = []; for (var i = 0; i < len; i++) r[i] = o; return r; } function createArray(len, o) { var r = []; for (var i = 0; i < len; i++) r[i] = o; return r; }
var getterCalls; var getterCalls;
var magicObject = createArray(10, {abcdefg: [1,2,5,"ab", null, undefined, true, false,,], var magicObject = createArray(10, {abcdefg: [1,2,5,"ab", null, undefined, true, false,,],
......
...@@ -58,10 +58,10 @@ function (jsonObject){ ...@@ -58,10 +58,10 @@ function (jsonObject){
PASS tests[i](nativeJSON) is tests[i].expected PASS tests[i](nativeJSON) is tests[i].expected
function (jsonObject){ function (jsonObject){
var value = new Boolean(true); var value = new Boolean(true);
value.valueOf = function() { return 2; }; value.valueOf = function() { return false; };
return jsonObject.stringify(value); return jsonObject.stringify(value);
} }
FAIL tests[i](nativeJSON) should be 2. Was true. PASS tests[i](nativeJSON) is tests[i].expected
function (jsonObject){ function (jsonObject){
var value = new String("fail"); var value = new String("fail");
value.toString = function() { return "converted string"; }; value.toString = function() { return "converted string"; };
...@@ -91,7 +91,7 @@ PASS tests[i](nativeJSON) is tests[i](JSON) ...@@ -91,7 +91,7 @@ PASS tests[i](nativeJSON) is tests[i](JSON)
function (jsonObject){ function (jsonObject){
return jsonObject.stringify({toJSON: Date.prototype.toJSON, toISOString: function(){ return {}; }}); return jsonObject.stringify({toJSON: Date.prototype.toJSON, toISOString: function(){ return {}; }});
} }
FAIL tests[i](nativeJSON) should throw an exception. Was {}. PASS tests[i](nativeJSON) is tests[i].expected
function (jsonObject){ function (jsonObject){
return jsonObject.stringify({toJSON: Date.prototype.toJSON, toISOString: function(){ throw "An exception"; }}); return jsonObject.stringify({toJSON: Date.prototype.toJSON, toISOString: function(){ throw "An exception"; }});
} }
...@@ -143,7 +143,7 @@ function (jsonObject){ ...@@ -143,7 +143,7 @@ function (jsonObject){
jsonObject.stringify([1,2,3,4,5], function(k,v){allString = allString && (typeof k == "string"); return v}); jsonObject.stringify([1,2,3,4,5], function(k,v){allString = allString && (typeof k == "string"); return v});
return allString; return allString;
} }
FAIL tests[i](nativeJSON) should be false. Was true. PASS tests[i](nativeJSON) is tests[i].expected
function (jsonObject){ function (jsonObject){
var allString = true; var allString = true;
var array = []; var array = [];
...@@ -355,11 +355,11 @@ PASS tests[i](nativeJSON) is tests[i](JSON) ...@@ -355,11 +355,11 @@ PASS tests[i](nativeJSON) is tests[i](JSON)
function (jsonObject){ function (jsonObject){
return jsonObject.stringify(objectWithSideEffectGetter); return jsonObject.stringify(objectWithSideEffectGetter);
} }
FAIL tests[i](nativeJSON) should be {"foo":1}. Was {}. PASS tests[i](nativeJSON) is tests[i].expected
function (jsonObject){ function (jsonObject){
return jsonObject.stringify(objectWithSideEffectGetterAndProto); return jsonObject.stringify(objectWithSideEffectGetterAndProto);
} }
FAIL tests[i](nativeJSON) should be {"foo":1}. Was {}. PASS tests[i](nativeJSON) is tests[i].expected
function (jsonObject){ function (jsonObject){
return jsonObject.stringify(arrayWithSideEffectGetter); return jsonObject.stringify(arrayWithSideEffectGetter);
} }
...@@ -373,7 +373,7 @@ function (jsonObject){ ...@@ -373,7 +373,7 @@ function (jsonObject){
jsonObject.stringify([1,2,3,,,,4,5,6], replaceFunc); jsonObject.stringify([1,2,3,,,,4,5,6], replaceFunc);
return replaceTracker; return replaceTracker;
} }
FAIL tests[i](nativeJSON) should be (string)[1,2,3,null,null,null,4,5,6];0(number)1;1(number)2;2(number)3;3(number)undefined;4(number)undefined;5(number)undefined;6(number)4;7(number)5;8(number)6;. Was (string)[1,2,3,null,null,null,4,5,6];0(string)1;1(string)2;2(string)3;3(string)undefined;4(string)undefined;5(string)undefined;6(string)4;7(string)5;8(string)6;. PASS tests[i](nativeJSON) is tests[i].expected
function (jsonObject){ function (jsonObject){
replaceTracker = ""; replaceTracker = "";
jsonObject.stringify({a:"a", b:"b", c:"c", 3: "d", 2: "e", 1: "f"}, replaceFunc); jsonObject.stringify({a:"a", b:"b", c:"c", 3: "d", 2: "e", 1: "f"}, replaceFunc);
...@@ -451,7 +451,7 @@ function (jsonObject){ ...@@ -451,7 +451,7 @@ function (jsonObject){
try { jsonObject.stringify(cyclicArray); } catch { cycleTracker += " -> exception" } try { jsonObject.stringify(cyclicArray); } catch { cycleTracker += " -> exception" }
return cycleTracker; return cycleTracker;
} }
FAIL tests[i](nativeJSON) should be 0(number):[object Object]first, -> exception. Was 0(string):[object Object]first, -> exception. PASS tests[i](nativeJSON) is tests[i].expected
function (jsonObject){ function (jsonObject){
getterCalls = 0; getterCalls = 0;
return jsonObject.stringify(magicObject) + " :: getter calls = " + getterCalls; return jsonObject.stringify(magicObject) + " :: getter calls = " + getterCalls;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment