From dc2da1558f6f8c1c750f2ee9950d605189c64fc9 Mon Sep 17 00:00:00 2001
From: Leo Balter <leonardo.balter@gmail.com>
Date: Tue, 9 Oct 2018 17:06:19 -0400
Subject: [PATCH] Add tests for the resolved namespace obj

---
 .../imported-Symbol-toStringTag.case          | 29 +++++++
 src/dynamic-import/imported-extensible.case   | 12 +++
 src/dynamic-import/imported-no-iterator.case  | 13 +++
 src/dynamic-import/imported-prop-descs.case   | 34 ++++++++
 src/dynamic-import/imported-prototype.case    | 11 +++
 .../module-namespace-object/await.template    | 81 +++++++++++++++++++
 .../module-namespace-object/promise.template  | 79 ++++++++++++++++++
 .../module-code_FIXTURE.js                    |  8 ++
 8 files changed, 267 insertions(+)
 create mode 100644 src/dynamic-import/imported-Symbol-toStringTag.case
 create mode 100644 src/dynamic-import/imported-extensible.case
 create mode 100644 src/dynamic-import/imported-no-iterator.case
 create mode 100644 src/dynamic-import/imported-prop-descs.case
 create mode 100644 src/dynamic-import/imported-prototype.case
 create mode 100644 src/dynamic-import/module-namespace-object/await.template
 create mode 100644 src/dynamic-import/module-namespace-object/promise.template
 create mode 100644 test/language/module-code/dynamic-import/module-namespace-object/module-code_FIXTURE.js

diff --git a/src/dynamic-import/imported-Symbol-toStringTag.case b/src/dynamic-import/imported-Symbol-toStringTag.case
new file mode 100644
index 0000000000..99d43b22da
--- /dev/null
+++ b/src/dynamic-import/imported-Symbol-toStringTag.case
@@ -0,0 +1,29 @@
+// Copyright (C) 2018 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: Module namespace objects have a Symbol.toStringTag
+template: module-namespace-object
+info: |
+    @@toStringTag
+
+        The initial value of the @@toStringTag property is the String value "Module".
+
+        This property has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+            [[Configurable]]: false }.
+features: [Symbol.toStringTag]
+---*/
+
+//- import
+import('./module-code_FIXTURE.js')
+//- body
+assert.sameValue(imported[Symbol.toStringTag], 'Module');
+
+// propertyHelper.js is not appropriate for this test because it assumes that
+// the object exposes the ordinary object's implementation of [[Get]], [[Set]],
+// [[Delete]], and [[OwnPropertyKeys]], which the module namespace exotic
+// object does not.
+var desc = Object.getOwnPropertyDescriptor(imported, Symbol.toStringTag);
+
+assert.sameValue(desc.enumerable, false, 'reports as non-enumerable');
+assert.sameValue(desc.writable, false, 'reports as non-writable');
+assert.sameValue(desc.configurable, false, 'reports as non-configurable');
diff --git a/src/dynamic-import/imported-extensible.case b/src/dynamic-import/imported-extensible.case
new file mode 100644
index 0000000000..15e87c6097
--- /dev/null
+++ b/src/dynamic-import/imported-extensible.case
@@ -0,0 +1,12 @@
+// Copyright (C) 2018 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: Module namespace objects are not extensible.
+template: module-namespace-object
+includes: [propertyHelper.js]
+---*/
+
+//- import
+import('./module-code_FIXTURE.js')
+//- body
+assert.sameValue(Object.isExtensible(imported), false);
diff --git a/src/dynamic-import/imported-no-iterator.case b/src/dynamic-import/imported-no-iterator.case
new file mode 100644
index 0000000000..0999a89ddd
--- /dev/null
+++ b/src/dynamic-import/imported-no-iterator.case
@@ -0,0 +1,13 @@
+// Copyright (C) 2016 Kevin Gibbons. All rights reserved.
+// Copyright (C) 2018 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: Module namespace objects lack a Symbol.toStringTag
+template: module-namespace-object
+features: [Symbol.iterator]
+---*/
+
+//- import
+import('./module-code_FIXTURE.js')
+//- body
+assert.sameValue(Object.prototype.hasOwnProperty.call(imported, Symbol.iterator), false);
diff --git a/src/dynamic-import/imported-prop-descs.case b/src/dynamic-import/imported-prop-descs.case
new file mode 100644
index 0000000000..55edf6daa1
--- /dev/null
+++ b/src/dynamic-import/imported-prop-descs.case
@@ -0,0 +1,34 @@
+// Copyright (C) 2018 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: imported object properties descriptors
+template: module-namespace-object
+---*/
+
+//- import
+import('./module-code_FIXTURE.js')
+//- body
+// propertyHelper.js is not appropriate for this test because it assumes that
+// the object exposes the ordinary object's implementation of [[Get]], [[Set]],
+// [[Delete]], and [[OwnPropertyKeys]], which the module namespace exotic
+// object does not.
+var desc = Object.getOwnPropertyDescriptor(imported, 'default');
+
+assert.sameValue(desc.value, 42, 'default value is 42');
+assert.sameValue(desc.enumerable, true, 'default reports as enumerable');
+assert.sameValue(desc.writable, true, 'default reports as writable');
+assert.sameValue(desc.configurable, false, 'default reports as non-configurable');
+
+desc = Object.getOwnPropertyDescriptor(imported, 'x');
+
+assert.sameValue(desc.value, 'Test262', 'x value is "Test262"');
+assert.sameValue(desc.enumerable, true, 'x reports as enumerable');
+assert.sameValue(desc.writable, true, 'x reports as writable');
+assert.sameValue(desc.configurable, false, 'x reports as non-configurable');
+
+desc = Object.getOwnPropertyDescriptor(imported, 'z');
+
+assert.sameValue(desc.value, 42, 'z value is 42');
+assert.sameValue(desc.enumerable, true, 'z reports as enumerable');
+assert.sameValue(desc.writable, true, 'z reports as writable');
+assert.sameValue(desc.configurable, false, 'z reports as non-configurable');
diff --git a/src/dynamic-import/imported-prototype.case b/src/dynamic-import/imported-prototype.case
new file mode 100644
index 0000000000..fd5c281749
--- /dev/null
+++ b/src/dynamic-import/imported-prototype.case
@@ -0,0 +1,11 @@
+// Copyright (C) 2018 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: Module namespace object prototype is null
+template: module-namespace-object
+---*/
+
+//- import
+import('./module-code_FIXTURE.js')
+//- body
+assert.sameValue(Object.getPrototypeOf(imported), null, 'prototype is null');
diff --git a/src/dynamic-import/module-namespace-object/await.template b/src/dynamic-import/module-namespace-object/await.template
new file mode 100644
index 0000000000..bc79c102ab
--- /dev/null
+++ b/src/dynamic-import/module-namespace-object/await.template
@@ -0,0 +1,81 @@
+// Copyright (C) 2018 Leo Balter. All rights reserved.
+// Copyright (C) 2018 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+path: language/module-code/dynamic-import/module-namespace-object/await-
+name: value from await resolving
+esid: sec-finishdynamicimport
+info: |
+    Runtime Semantics: FinishDynamicImport ( referencingScriptOrModule, specifier, promiseCapability, completion )
+
+        1. If completion is an abrupt completion, ...
+        2. Otherwise,
+            ...
+            d. Let namespace be GetModuleNamespace(moduleRecord).
+            e. If namespace is an abrupt completion, perform ! Call(promiseCapability.[[Reject]], undefined, « namespace.[[Value]] »).
+            f. Otherwise, perform ! Call(promiseCapability.[[Resolve]], undefined, « namespace.[[Value]] »).
+
+    Runtime Semantics: GetModuleNamespace ( module )
+
+        ...
+        3. Let namespace be module.[[Namespace]].
+        4. If namespace is undefined, then
+            a. Let exportedNames be ? module.GetExportedNames(« »).
+            b. Let unambiguousNames be a new empty List.
+            c. For each name that is an element of exportedNames, do
+                i. Let resolution be ? module.ResolveExport(name, « »).
+                ii. If resolution is a ResolvedBinding Record, append name to unambiguousNames.
+            d. Set namespace to ModuleNamespaceCreate(module, unambiguousNames).
+        5. Return namespace.
+
+    ModuleNamespaceCreate ( module, exports )
+
+        ...
+        4. Let M be a newly created object.
+        5. Set M's essential internal methods to the definitions specified in 9.4.6.
+        7. Let sortedExports be a new List containing the same values as the list exports where the
+        values are ordered as if an Array of the same values had been sorted using Array.prototype.sort
+        using undefined as comparefn.
+        8. Set M.[[Exports]] to sortedExports.
+        9. Create own properties of M corresponding to the definitions in 26.3.
+        10. Set module.[[Namespace]] to M.
+        11. Return M.
+
+    26.3 Module Namespace Objects
+
+        A Module Namespace Object is a module namespace exotic object that provides runtime
+        property-based access to a module's exported bindings. There is no constructor function for
+        Module Namespace Objects. Instead, such an object is created for each module that is imported
+        by an ImportDeclaration that includes a NameSpaceImport.
+
+        In addition to the properties specified in 9.4.6 each Module Namespace Object has the
+        following own property:
+
+    26.3.1 @@toStringTag
+
+        The initial value of the @@toStringTag property is the String value "Module".
+
+        This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.
+
+    Module Namespace Exotic Objects
+
+        A module namespace object is an exotic object that exposes the bindings exported from an
+        ECMAScript Module (See 15.2.3). There is a one-to-one correspondence between the String-keyed
+        own properties of a module namespace exotic object and the binding names exported by the
+        Module. The exported bindings include any bindings that are indirectly exported using export *
+        export items. Each String-valued own property key is the StringValue of the corresponding
+        exported binding name. These are the only String-keyed properties of a module namespace exotic
+        object. Each such property has the attributes { [[Writable]]: true, [[Enumerable]]: true,
+        [[Configurable]]: false }. Module namespace objects are not extensible.
+
+features: [dynamic-import]
+flags: [async]
+---*/
+
+async function fn() {
+    const imported = await /*{ import }*/;
+
+    /*{ body }*/
+}
+
+fn().then($DONE, $DONE).catch($DONE);
diff --git a/src/dynamic-import/module-namespace-object/promise.template b/src/dynamic-import/module-namespace-object/promise.template
new file mode 100644
index 0000000000..7da1a8e9c5
--- /dev/null
+++ b/src/dynamic-import/module-namespace-object/promise.template
@@ -0,0 +1,79 @@
+// Copyright (C) 2018 Leo Balter. All rights reserved.
+// Copyright (C) 2018 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+path: language/module-code/dynamic-import/module-namespace-object/promise-then-
+name: value from promise then
+esid: sec-finishdynamicimport
+info: |
+    Runtime Semantics: FinishDynamicImport ( referencingScriptOrModule, specifier, promiseCapability, completion )
+
+        1. If completion is an abrupt completion, ...
+        2. Otherwise,
+            ...
+            d. Let namespace be GetModuleNamespace(moduleRecord).
+            e. If namespace is an abrupt completion, perform ! Call(promiseCapability.[[Reject]], undefined, « namespace.[[Value]] »).
+            f. Otherwise, perform ! Call(promiseCapability.[[Resolve]], undefined, « namespace.[[Value]] »).
+
+    Runtime Semantics: GetModuleNamespace ( module )
+
+        ...
+        3. Let namespace be module.[[Namespace]].
+        4. If namespace is undefined, then
+            a. Let exportedNames be ? module.GetExportedNames(« »).
+            b. Let unambiguousNames be a new empty List.
+            c. For each name that is an element of exportedNames, do
+                i. Let resolution be ? module.ResolveExport(name, « »).
+                ii. If resolution is a ResolvedBinding Record, append name to unambiguousNames.
+            d. Set namespace to ModuleNamespaceCreate(module, unambiguousNames).
+        5. Return namespace.
+
+    ModuleNamespaceCreate ( module, exports )
+
+        ...
+        4. Let M be a newly created object.
+        5. Set M's essential internal methods to the definitions specified in 9.4.6.
+        7. Let sortedExports be a new List containing the same values as the list exports where the
+        values are ordered as if an Array of the same values had been sorted using Array.prototype.sort
+        using undefined as comparefn.
+        8. Set M.[[Exports]] to sortedExports.
+        9. Create own properties of M corresponding to the definitions in 26.3.
+        10. Set module.[[Namespace]] to M.
+        11. Return M.
+
+    26.3 Module Namespace Objects
+
+        A Module Namespace Object is a module namespace exotic object that provides runtime
+        property-based access to a module's exported bindings. There is no constructor function for
+        Module Namespace Objects. Instead, such an object is created for each module that is imported
+        by an ImportDeclaration that includes a NameSpaceImport.
+
+        In addition to the properties specified in 9.4.6 each Module Namespace Object has the
+        following own property:
+
+    26.3.1 @@toStringTag
+
+        The initial value of the @@toStringTag property is the String value "Module".
+
+        This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.
+
+    Module Namespace Exotic Objects
+
+        A module namespace object is an exotic object that exposes the bindings exported from an
+        ECMAScript Module (See 15.2.3). There is a one-to-one correspondence between the String-keyed
+        own properties of a module namespace exotic object and the binding names exported by the
+        Module. The exported bindings include any bindings that are indirectly exported using export *
+        export items. Each String-valued own property key is the StringValue of the corresponding
+        exported binding name. These are the only String-keyed properties of a module namespace exotic
+        object. Each such property has the attributes { [[Writable]]: true, [[Enumerable]]: true,
+        [[Configurable]]: false }. Module namespace objects are not extensible.
+
+features: [dynamic-import]
+flags: [async]
+---*/
+
+/*{ import }*/.then(imported => {
+
+    /*{ body }*/
+
+}).then($DONE, $DONE).catch($DONE);
diff --git a/test/language/module-code/dynamic-import/module-namespace-object/module-code_FIXTURE.js b/test/language/module-code/dynamic-import/module-namespace-object/module-code_FIXTURE.js
new file mode 100644
index 0000000000..96b0503d95
--- /dev/null
+++ b/test/language/module-code/dynamic-import/module-namespace-object/module-code_FIXTURE.js
@@ -0,0 +1,8 @@
+// Copyright (C) 2018 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+const x = 'Test262';
+const y = 42;
+
+export default y;
+export { x, y as z };
-- 
GitLab