From e793512b55c199de6abc392d1be4de7325dae544 Mon Sep 17 00:00:00 2001
From: Mike Pennisi <mike@mikepennisi.com>
Date: Fri, 28 May 2021 18:58:03 -0400
Subject: [PATCH] Add tests for the "JSON modules" language proposal

https://github.com/tc39/proposal-json-modules

This proposal advanced to Stage 3 of TC39's standardization process on
2021-01-27.
---
 .../import/json-extensibility-array.js        | 20 ++++++
 .../import/json-extensibility-object.js       | 20 ++++++
 .../json-idempotency-indirect_FIXTURE.js      |  6 ++
 test/language/import/json-idempotency.js      | 21 ++++++
 .../import/json-idempotency_FIXTURE.json      |  1 +
 test/language/import/json-invalid.js          | 23 +++++++
 .../language/import/json-invalid_FIXTURE.json |  3 +
 test/language/import/json-named-bindings.js   | 20 ++++++
 .../import/json-named-bindings_FIXTURE.json   |  3 +
 test/language/import/json-value-array.js      | 47 +++++++++++++
 .../import/json-value-array_FIXTURE.json      | 10 +++
 test/language/import/json-value-boolean.js    | 20 ++++++
 .../import/json-value-boolean_FIXTURE.json    |  1 +
 test/language/import/json-value-null.js       | 20 ++++++
 .../import/json-value-null_FIXTURE.json       |  1 +
 test/language/import/json-value-number.js     | 20 ++++++
 .../import/json-value-number_FIXTURE.json     |  1 +
 test/language/import/json-value-object.js     | 67 +++++++++++++++++++
 .../import/json-value-object_FIXTURE.json     | 10 +++
 test/language/import/json-value-string.js     | 20 ++++++
 .../import/json-value-string_FIXTURE.json     |  1 +
 test/language/import/json-via-namespace.js    | 13 ++++
 .../import/json-via-namespace_FIXTURE.json    |  1 +
 23 files changed, 349 insertions(+)
 create mode 100644 test/language/import/json-extensibility-array.js
 create mode 100644 test/language/import/json-extensibility-object.js
 create mode 100644 test/language/import/json-idempotency-indirect_FIXTURE.js
 create mode 100644 test/language/import/json-idempotency.js
 create mode 100644 test/language/import/json-idempotency_FIXTURE.json
 create mode 100644 test/language/import/json-invalid.js
 create mode 100644 test/language/import/json-invalid_FIXTURE.json
 create mode 100644 test/language/import/json-named-bindings.js
 create mode 100644 test/language/import/json-named-bindings_FIXTURE.json
 create mode 100644 test/language/import/json-value-array.js
 create mode 100644 test/language/import/json-value-array_FIXTURE.json
 create mode 100644 test/language/import/json-value-boolean.js
 create mode 100644 test/language/import/json-value-boolean_FIXTURE.json
 create mode 100644 test/language/import/json-value-null.js
 create mode 100644 test/language/import/json-value-null_FIXTURE.json
 create mode 100644 test/language/import/json-value-number.js
 create mode 100644 test/language/import/json-value-number_FIXTURE.json
 create mode 100644 test/language/import/json-value-object.js
 create mode 100644 test/language/import/json-value-object_FIXTURE.json
 create mode 100644 test/language/import/json-value-string.js
 create mode 100644 test/language/import/json-value-string_FIXTURE.json
 create mode 100644 test/language/import/json-via-namespace.js
 create mode 100644 test/language/import/json-via-namespace_FIXTURE.json

diff --git a/test/language/import/json-extensibility-array.js b/test/language/import/json-extensibility-array.js
new file mode 100644
index 0000000000..3d2ae3520a
--- /dev/null
+++ b/test/language/import/json-extensibility-array.js
@@ -0,0 +1,20 @@
+// Copyright (C) 2021 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-parse-json-module
+description: Creates extensible arrays
+flags: [module]
+includes: [propertyHelper.js]
+features: [json-modules]
+---*/
+
+import value from './json-value-array_FIXTURE.json' assert { type: 'json' };
+
+value.test262property = 'test262 value';
+
+verifyProperty(value, 'test262property', {
+  value: 'test262 value',
+  writable: true,
+  enumerable: true,
+  configurable: true
+});
diff --git a/test/language/import/json-extensibility-object.js b/test/language/import/json-extensibility-object.js
new file mode 100644
index 0000000000..2004cc0c33
--- /dev/null
+++ b/test/language/import/json-extensibility-object.js
@@ -0,0 +1,20 @@
+// Copyright (C) 2021 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-parse-json-module
+description: Creates extensible objects
+flags: [module]
+includes: [propertyHelper.js]
+features: [json-modules]
+---*/
+
+import value from './json-value-object_FIXTURE.json' assert { type: 'json' };
+
+value.test262property = 'test262 value';
+
+verifyProperty(value, 'test262property', {
+  value: 'test262 value',
+  writable: true,
+  enumerable: true,
+  configurable: true
+});
diff --git a/test/language/import/json-idempotency-indirect_FIXTURE.js b/test/language/import/json-idempotency-indirect_FIXTURE.js
new file mode 100644
index 0000000000..61c440b333
--- /dev/null
+++ b/test/language/import/json-idempotency-indirect_FIXTURE.js
@@ -0,0 +1,6 @@
+// Copyright (C) 2021 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+import value from './json-idempotency_FIXTURE.json' assert { type: 'json' };
+
+globalThis.viaSecondModule = value;
diff --git a/test/language/import/json-idempotency.js b/test/language/import/json-idempotency.js
new file mode 100644
index 0000000000..c75644c324
--- /dev/null
+++ b/test/language/import/json-idempotency.js
@@ -0,0 +1,21 @@
+// Copyright (C) 2021 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-parse-json-module
+description: The same object representation is returned to all import sites
+flags: [module, async]
+features: [json-modules, globalThis, dynamic-import]
+---*/
+
+import viaStaticImport1 from './json-idempotency_FIXTURE.json' assert { type: 'json' };
+import {default as viaStaticImport2} from './json-idempotency_FIXTURE.json' assert { type: 'json' };
+import './json-idempotency-indirect_FIXTURE.js';
+
+assert.sameValue(viaStaticImport1, viaStaticImport2);
+assert.sameValue(globalThis.viaSecondModule, viaStaticImport1);
+
+import('./json-idempotency_FIXTURE.json', { assert: { type: 'json' } })
+  .then(function(viaDynamicImport) {
+    assert.sameValue(viaDynamicImport.default, viaStaticImport1);
+  })
+  .then($DONE, $DONE);
diff --git a/test/language/import/json-idempotency_FIXTURE.json b/test/language/import/json-idempotency_FIXTURE.json
new file mode 100644
index 0000000000..0967ef424b
--- /dev/null
+++ b/test/language/import/json-idempotency_FIXTURE.json
@@ -0,0 +1 @@
+{}
diff --git a/test/language/import/json-invalid.js b/test/language/import/json-invalid.js
new file mode 100644
index 0000000000..9e118beec0
--- /dev/null
+++ b/test/language/import/json-invalid.js
@@ -0,0 +1,23 @@
+// Copyright (C) 2021 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-parse-json-module
+description: Does not define
+info: |
+  # 1.4 ParseJSONModule ( source )
+
+  The abstract operation ParseJSONModule takes a single argument source which
+  is a String representing the contents of a module.
+
+  1. Let json be ? Call(%JSON.parse%, undefined, « source »).
+  2. Return CreateDefaultExportSyntheticModule(json).
+flags: [module]
+features: [json-modules]
+negative:
+  phase: parse
+  type: SyntaxError
+---*/
+
+$DONOTEVALUATE();
+
+import value from './json-invalid_FIXTURE.json' assert { type: 'json' };
diff --git a/test/language/import/json-invalid_FIXTURE.json b/test/language/import/json-invalid_FIXTURE.json
new file mode 100644
index 0000000000..64809bccc4
--- /dev/null
+++ b/test/language/import/json-invalid_FIXTURE.json
@@ -0,0 +1,3 @@
+{
+  notJson: 0
+}
diff --git a/test/language/import/json-named-bindings.js b/test/language/import/json-named-bindings.js
new file mode 100644
index 0000000000..e1dc37350a
--- /dev/null
+++ b/test/language/import/json-named-bindings.js
@@ -0,0 +1,20 @@
+// Copyright (C) 2021 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-parse-json-module
+description: Does not define named bindings
+info: |
+  In the early design of JSON modules, contributors considered allowing the
+  properties of object values in JSON modules to be imported directly by name.
+  This was ultimately rejected, so attempting to import in this way should
+  produce a SyntaxError.
+flags: [module]
+features: [json-modules]
+negative:
+  phase: parse
+  type: SyntaxError
+---*/
+
+$DONOTEVALUATE();
+
+import {name} from './json-named-bindings_FIXTURE.json' assert { type: 'json' };
diff --git a/test/language/import/json-named-bindings_FIXTURE.json b/test/language/import/json-named-bindings_FIXTURE.json
new file mode 100644
index 0000000000..ead2bb7c66
--- /dev/null
+++ b/test/language/import/json-named-bindings_FIXTURE.json
@@ -0,0 +1,3 @@
+{
+  "name": 0
+}
diff --git a/test/language/import/json-value-array.js b/test/language/import/json-value-array.js
new file mode 100644
index 0000000000..66a59b4aca
--- /dev/null
+++ b/test/language/import/json-value-array.js
@@ -0,0 +1,47 @@
+// Copyright (C) 2021 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-parse-json-module
+description: Correctly parses the JSON representation of an array
+info: |
+  # 1.4 ParseJSONModule ( source )
+
+  The abstract operation ParseJSONModule takes a single argument source which
+  is a String representing the contents of a module.
+
+  1. Let json be ? Call(%JSON.parse%, undefined, « source »).
+  2. Return CreateDefaultExportSyntheticModule(json).
+
+  To more fully verify parsing correctness, the source text of the imported
+  module record includes non-printable characters (specifically, all four forms
+  of JSON's so-called "whitespace" token) both before and after the "value."
+flags: [module]
+features: [json-modules]
+---*/
+
+import value from './json-value-array_FIXTURE.json' assert { type: 'json' };
+
+assert(Array.isArray(value), 'the exported value is an array');
+assert.sameValue(
+  Object.getPrototypeOf(value),
+  Array.prototype,
+  'the exported value is not a subclass of Array'
+);
+assert.sameValue(Object.getOwnPropertyNames(value).length, 7);
+assert.sameValue(value.length, 6);
+
+assert.sameValue(value[0], -1.2345);
+assert.sameValue(value[1], true);
+assert.sameValue(value[2], 'a string value');
+assert.sameValue(value[3], null);
+
+assert.sameValue(Object.getPrototypeOf(value[4]), Object.prototype);
+assert.sameValue(Object.getOwnPropertyNames(value[4]).length, 0);
+
+assert(Array.isArray(value[5]), 'the fifth element is an array');
+assert.sameValue(
+  Object.getPrototypeOf(value[5]),
+  Array.prototype,
+  'the fifth element is not a subclass of Array'
+);
+assert.sameValue(Object.getOwnPropertyNames(value[5]).length, 1);
diff --git a/test/language/import/json-value-array_FIXTURE.json b/test/language/import/json-value-array_FIXTURE.json
new file mode 100644
index 0000000000..9520048793
--- /dev/null
+++ b/test/language/import/json-value-array_FIXTURE.json
@@ -0,0 +1,10 @@
+ 
+
	[
+  -1234.500e-003,
+  true,
+  "a string value",
+  null,
+  {},
+  []
+] 
+
	
diff --git a/test/language/import/json-value-boolean.js b/test/language/import/json-value-boolean.js
new file mode 100644
index 0000000000..faa2320a90
--- /dev/null
+++ b/test/language/import/json-value-boolean.js
@@ -0,0 +1,20 @@
+// Copyright (C) 2021 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-parse-json-module
+description: Correctly parses the JSON representation of a boolean
+info: |
+  # 1.4 ParseJSONModule ( source )
+
+  The abstract operation ParseJSONModule takes a single argument source which
+  is a String representing the contents of a module.
+
+  1. Let json be ? Call(%JSON.parse%, undefined, « source »).
+  2. Return CreateDefaultExportSyntheticModule(json).
+flags: [module]
+features: [json-modules]
+---*/
+
+import value from './json-value-boolean_FIXTURE.json' assert { type: 'json' };
+
+assert.sameValue(value, true);
diff --git a/test/language/import/json-value-boolean_FIXTURE.json b/test/language/import/json-value-boolean_FIXTURE.json
new file mode 100644
index 0000000000..27ba77ddaf
--- /dev/null
+++ b/test/language/import/json-value-boolean_FIXTURE.json
@@ -0,0 +1 @@
+true
diff --git a/test/language/import/json-value-null.js b/test/language/import/json-value-null.js
new file mode 100644
index 0000000000..af955c4bfc
--- /dev/null
+++ b/test/language/import/json-value-null.js
@@ -0,0 +1,20 @@
+// Copyright (C) 2021 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-parse-json-module
+description: Correctly parses the JSON representation of null
+info: |
+  # 1.4 ParseJSONModule ( source )
+
+  The abstract operation ParseJSONModule takes a single argument source which
+  is a String representing the contents of a module.
+
+  1. Let json be ? Call(%JSON.parse%, undefined, « source »).
+  2. Return CreateDefaultExportSyntheticModule(json).
+flags: [module]
+features: [json-modules]
+---*/
+
+import value from './json-value-null_FIXTURE.json' assert { type: 'json' };
+
+assert.sameValue(value, null);
diff --git a/test/language/import/json-value-null_FIXTURE.json b/test/language/import/json-value-null_FIXTURE.json
new file mode 100644
index 0000000000..19765bd501
--- /dev/null
+++ b/test/language/import/json-value-null_FIXTURE.json
@@ -0,0 +1 @@
+null
diff --git a/test/language/import/json-value-number.js b/test/language/import/json-value-number.js
new file mode 100644
index 0000000000..3113fd4741
--- /dev/null
+++ b/test/language/import/json-value-number.js
@@ -0,0 +1,20 @@
+// Copyright (C) 2021 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-parse-json-module
+description: Correctly parses the JSON representation of a number
+info: |
+  # 1.4 ParseJSONModule ( source )
+
+  The abstract operation ParseJSONModule takes a single argument source which
+  is a String representing the contents of a module.
+
+  1. Let json be ? Call(%JSON.parse%, undefined, « source »).
+  2. Return CreateDefaultExportSyntheticModule(json).
+flags: [module]
+features: [json-modules]
+---*/
+
+import value from './json-value-number_FIXTURE.json' assert { type: 'json' };
+
+assert.sameValue(value, -1.2345);
diff --git a/test/language/import/json-value-number_FIXTURE.json b/test/language/import/json-value-number_FIXTURE.json
new file mode 100644
index 0000000000..859603baed
--- /dev/null
+++ b/test/language/import/json-value-number_FIXTURE.json
@@ -0,0 +1 @@
+-1234.500e-003
diff --git a/test/language/import/json-value-object.js b/test/language/import/json-value-object.js
new file mode 100644
index 0000000000..242b472f98
--- /dev/null
+++ b/test/language/import/json-value-object.js
@@ -0,0 +1,67 @@
+// Copyright (C) 2021 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-parse-json-module
+description: Correctly parses the JSON representation of an ordinary object
+info: |
+  # 1.4 ParseJSONModule ( source )
+
+  The abstract operation ParseJSONModule takes a single argument source which
+  is a String representing the contents of a module.
+
+  1. Let json be ? Call(%JSON.parse%, undefined, « source »).
+  2. Return CreateDefaultExportSyntheticModule(json).
+
+  To more fully verify parsing correctness, the source text of the imported
+  module record includes non-printable characters (specifically, all four forms
+  of JSON's so-called "whitespace" token) both before and after the "value."
+flags: [module]
+includes: [propertyHelper.js]
+features: [json-modules]
+---*/
+
+import value from './json-value-object_FIXTURE.json' assert { type: 'json' };
+
+assert.sameValue(Object.getPrototypeOf(value), Object.prototype);
+assert.sameValue(Object.getOwnPropertyNames(value).length, 6);
+
+verifyProperty(value, 'number', {
+  value: -1.2345,
+  writable: true,
+  enumerable: true,
+  configurable: true
+});
+
+verifyProperty(value, 'boolean', {
+  value: true,
+  writable: true,
+  enumerable: true,
+  configurable: true
+});
+
+verifyProperty(value, 'string', {
+  value: 'a string value',
+  writable: true,
+  enumerable: true,
+  configurable: true
+});
+
+verifyProperty(value, 'null', {
+  value: null,
+  writable: true,
+  enumerable: true,
+  configurable: true
+});
+
+assert.sameValue(Object.getPrototypeOf(value.object), Object.prototype);
+assert.sameValue(Object.getOwnPropertyNames(value.object).length, 0);
+
+assert(
+  Array.isArray(value.array), 'the value of the "array" property is an array'
+);
+assert.sameValue(
+  Object.getPrototypeOf(value.array),
+  Array.prototype,
+  'the value of the "array" property is not a subclass of Array'
+);
+assert.sameValue(Object.getOwnPropertyNames(value.array).length, 1);
diff --git a/test/language/import/json-value-object_FIXTURE.json b/test/language/import/json-value-object_FIXTURE.json
new file mode 100644
index 0000000000..814ec45e4d
--- /dev/null
+++ b/test/language/import/json-value-object_FIXTURE.json
@@ -0,0 +1,10 @@
+ 
+
	{
+  "number": -1234.500e-003,
+  "boolean": true,
+  "string": "a string value",
+  "null": null,
+  "object": {},
+  "array": []
+} 
+
	
diff --git a/test/language/import/json-value-string.js b/test/language/import/json-value-string.js
new file mode 100644
index 0000000000..c1da4d7e84
--- /dev/null
+++ b/test/language/import/json-value-string.js
@@ -0,0 +1,20 @@
+// Copyright (C) 2021 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-parse-json-module
+description: Correctly parses the JSON representation of a string
+info: |
+  # 1.4 ParseJSONModule ( source )
+
+  The abstract operation ParseJSONModule takes a single argument source which
+  is a String representing the contents of a module.
+
+  1. Let json be ? Call(%JSON.parse%, undefined, « source »).
+  2. Return CreateDefaultExportSyntheticModule(json).
+flags: [module]
+features: [json-modules]
+---*/
+
+import value from './json-value-string_FIXTURE.json' assert { type: 'json' };
+
+assert.sameValue(value, 'a string value');
diff --git a/test/language/import/json-value-string_FIXTURE.json b/test/language/import/json-value-string_FIXTURE.json
new file mode 100644
index 0000000000..d98e333143
--- /dev/null
+++ b/test/language/import/json-value-string_FIXTURE.json
@@ -0,0 +1 @@
+"a string value"
diff --git a/test/language/import/json-via-namespace.js b/test/language/import/json-via-namespace.js
new file mode 100644
index 0000000000..780bd614fb
--- /dev/null
+++ b/test/language/import/json-via-namespace.js
@@ -0,0 +1,13 @@
+// Copyright (C) 2021 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-parse-json-module
+description: May be imported via a module namespace object
+flags: [module]
+features: [json-modules]
+---*/
+
+import * as ns from './json-via-namespace_FIXTURE.json' assert { type: 'json' };
+
+assert.sameValue(Object.getOwnPropertyNames(ns).length, 1);
+assert.sameValue(ns.default, 262);
diff --git a/test/language/import/json-via-namespace_FIXTURE.json b/test/language/import/json-via-namespace_FIXTURE.json
new file mode 100644
index 0000000000..5484d82917
--- /dev/null
+++ b/test/language/import/json-via-namespace_FIXTURE.json
@@ -0,0 +1 @@
+262