From b0ec060e62f8e973d92cb7810adb59dfc2ef54ac Mon Sep 17 00:00:00 2001
From: Leo Balter <leonardo.balter@gmail.com>
Date: Tue, 9 Oct 2018 14:10:29 -0400
Subject: [PATCH] Add more cases for Dynamic Imports usage

- Add cases for mixing module and script code
- Rename test case from return promise to thenable
- Fix script code case with valid loaded fixture
- Add a test to assert a promise return
- Add case for specifier toString rejection
- Add case for specifier toString
- Test Assignment expression abrupt completion
- Test Promise return
---
 ...script-code-host-resolves-module-code.case | 18 +++++++
 .../eval-script-code-target.case              | 22 ++++++++
 ...rns-promise.case => returns-thenable.case} |  2 +-
 src/dynamic-import/script-code-valid.case     |  2 +-
 .../specifier-tostring-abrupt-rejects.case    | 36 +++++++++++++
 src/dynamic-import/specifier-tostring.case    | 38 +++++++++++++
 .../assign-expr-get-value-abrupt-throws.js    | 37 +++++++++++++
 .../catch/script-code_FIXTURE.js              |  7 +++
 .../dynamic-import-module_FIXTURE.js          |  4 ++
 .../dynamic-import/returns-promise.js         | 53 +++++++++++++++++++
 .../usage/module-code_FIXTURE.js              |  8 +++
 11 files changed, 225 insertions(+), 2 deletions(-)
 create mode 100644 src/dynamic-import/eval-script-code-host-resolves-module-code.case
 create mode 100644 src/dynamic-import/eval-script-code-target.case
 rename src/dynamic-import/{returns-promise.case => returns-thenable.case} (86%)
 create mode 100644 src/dynamic-import/specifier-tostring-abrupt-rejects.case
 create mode 100644 src/dynamic-import/specifier-tostring.case
 create mode 100644 test/language/module-code/dynamic-import/assign-expr-get-value-abrupt-throws.js
 create mode 100644 test/language/module-code/dynamic-import/catch/script-code_FIXTURE.js
 create mode 100644 test/language/module-code/dynamic-import/dynamic-import-module_FIXTURE.js
 create mode 100644 test/language/module-code/dynamic-import/returns-promise.js
 create mode 100644 test/language/module-code/dynamic-import/usage/module-code_FIXTURE.js

diff --git a/src/dynamic-import/eval-script-code-host-resolves-module-code.case b/src/dynamic-import/eval-script-code-host-resolves-module-code.case
new file mode 100644
index 0000000000..4963710137
--- /dev/null
+++ b/src/dynamic-import/eval-script-code-host-resolves-module-code.case
@@ -0,0 +1,18 @@
+// Copyright (C) 2018 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: import() from a ascript code can load a file with module code
+template: default
+---*/
+
+//- setup
+// This is still valid in script code, and should not be valid for module code
+// https://tc39.github.io/ecma262/#sec-scripts-static-semantics-lexicallydeclarednames
+var smoosh; function smoosh() {}
+
+//- import
+import('./module-code_FIXTURE.js')
+//- body
+assert.sameValue(imported.default, 42);
+assert.sameValue(imported.x, 'Test262');
+assert.sameValue(imported.z, 42);
diff --git a/src/dynamic-import/eval-script-code-target.case b/src/dynamic-import/eval-script-code-target.case
new file mode 100644
index 0000000000..a73dfc91d9
--- /dev/null
+++ b/src/dynamic-import/eval-script-code-target.case
@@ -0,0 +1,22 @@
+// Copyright (C) 2018 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+desc: >
+  import() from a module code can load a file with script code, but the target
+  is resolved into a Module Record
+info: |
+  Modules
+
+  Static Semantics: Early Errors
+  
+    ModuleBody : ModuleItemList
+    - It is a Syntax Error if the LexicallyDeclaredNames of ModuleItemList containsany duplicate entries.
+    - It is a Syntax Error if any element of the LexicallyDeclaredNames of ModuleItemList also occurs in the VarDeclaredNames of ModuleItemList.
+template: catch
+flags: [module]
+---*/
+
+//- import
+import('./script-code_FIXTURE.js')
+//- body
+assert.sameValue(error.name, 'SyntaxError');
diff --git a/src/dynamic-import/returns-promise.case b/src/dynamic-import/returns-thenable.case
similarity index 86%
rename from src/dynamic-import/returns-promise.case
rename to src/dynamic-import/returns-thenable.case
index e03f674d31..f62fe38919 100644
--- a/src/dynamic-import/returns-promise.case
+++ b/src/dynamic-import/returns-thenable.case
@@ -2,7 +2,7 @@
 // Copyright (C) 2018 the V8 project authors. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
-desc: Dynamic import() returns a Promise object.
+desc: Dynamic import() returns a thenable object.
 template: default
 ---*/
 
diff --git a/src/dynamic-import/script-code-valid.case b/src/dynamic-import/script-code-valid.case
index 1c4f813a06..8304af7ed2 100644
--- a/src/dynamic-import/script-code-valid.case
+++ b/src/dynamic-import/script-code-valid.case
@@ -11,4 +11,4 @@ template: syntax/valid
 var smoosh; function smoosh() {}
 
 //- import
-import('./script-code-valid.js')
+import('./empty_FIXTURE.js')
diff --git a/src/dynamic-import/specifier-tostring-abrupt-rejects.case b/src/dynamic-import/specifier-tostring-abrupt-rejects.case
new file mode 100644
index 0000000000..7a67f6ea9e
--- /dev/null
+++ b/src/dynamic-import/specifier-tostring-abrupt-rejects.case
@@ -0,0 +1,36 @@
+// Copyright (C) 2018 Rick Waldron. 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.
+/*---
+desc: >
+    Abrupt from ToString(specifier) rejects the promise
+esid: sec-moduleevaluation
+info: |
+    Import Calls
+
+    Runtime Semantics: Evaluation
+    
+    ImportCall : import(AssignmentExpression)
+    
+    1. Let referencingScriptOrModule be ! GetActiveScriptOrModule().
+    2. Let argRef be the result of evaluating AssignmentExpression.
+    3. Let specifier be ? GetValue(argRef).
+    4. Let promiseCapability be ! NewPromiseCapability(%Promise%).
+    5. Let specifierString be ToString(specifier).
+    6. IfAbruptRejectPromise(specifierString, promiseCapability).
+    7. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability).
+    8. Return promiseCapability.[[Promise]].
+template: catch
+---*/
+
+//- setup
+const obj = {
+    toString() {
+        throw 'custom error';
+    }
+};
+
+//- import
+import(obj)
+//- body
+assert.sameValue(error, 'custom error');
diff --git a/src/dynamic-import/specifier-tostring.case b/src/dynamic-import/specifier-tostring.case
new file mode 100644
index 0000000000..d09cca31bd
--- /dev/null
+++ b/src/dynamic-import/specifier-tostring.case
@@ -0,0 +1,38 @@
+// Copyright (C) 2018 Rick Waldron. 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.
+/*---
+desc: >
+    ToString value of specifier
+esid: sec-moduleevaluation
+info: |
+    Import Calls
+
+    Runtime Semantics: Evaluation
+    
+    ImportCall : import(AssignmentExpression)
+    
+    1. Let referencingScriptOrModule be ! GetActiveScriptOrModule().
+    2. Let argRef be the result of evaluating AssignmentExpression.
+    3. Let specifier be ? GetValue(argRef).
+    4. Let promiseCapability be ! NewPromiseCapability(%Promise%).
+    5. Let specifierString be ToString(specifier).
+    6. IfAbruptRejectPromise(specifierString, promiseCapability).
+    7. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability).
+    8. Return promiseCapability.[[Promise]].
+template: default
+---*/
+
+//- setup
+const obj = {
+    toString() {
+        return './module-code_FIXTURE.js';
+    }
+};
+
+//- import
+import(obj)
+//- body
+assert.sameValue(imported.default, 42);
+assert.sameValue(imported.x, 'Test262');
+assert.sameValue(imported.z, 42);
diff --git a/test/language/module-code/dynamic-import/assign-expr-get-value-abrupt-throws.js b/test/language/module-code/dynamic-import/assign-expr-get-value-abrupt-throws.js
new file mode 100644
index 0000000000..acd0d96a7f
--- /dev/null
+++ b/test/language/module-code/dynamic-import/assign-expr-get-value-abrupt-throws.js
@@ -0,0 +1,37 @@
+// Copyright (C) 2018 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    Return Abrupt from the GetValue evaluation on the given AssignmentExpression
+esid: sec-import-call-runtime-semantics-evaluation
+info: |
+    Import Calls
+
+    Runtime Semantics: Evaluation
+    
+    ImportCall : import(AssignmentExpression)
+    
+    1. Let referencingScriptOrModule be ! GetActiveScriptOrModule().
+    2. Let argRef be the result of evaluating AssignmentExpression.
+    3. Let specifier be ? GetValue(argRef).
+    4. Let promiseCapability be ! NewPromiseCapability(%Promise%).
+    5. Let specifierString be ToString(specifier).
+    6. IfAbruptRejectPromise(specifierString, promiseCapability).
+    7. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability).
+    8. Return promiseCapability.[[Promise]].
+features: [dynamic-import]
+---*/
+
+const obj = {
+    get err() {
+        throw new Test262Error('catpure this on evaluation')
+    }
+}
+
+assert.throws(Test262Error, function() {
+    import(obj.err);
+}, 'Custom Error getting property value');
+
+assert.throws(ReferenceError, function() {
+    import(refErr);
+}, 'bad reference');
diff --git a/test/language/module-code/dynamic-import/catch/script-code_FIXTURE.js b/test/language/module-code/dynamic-import/catch/script-code_FIXTURE.js
new file mode 100644
index 0000000000..131ffcee71
--- /dev/null
+++ b/test/language/module-code/dynamic-import/catch/script-code_FIXTURE.js
@@ -0,0 +1,7 @@
+// Copyright (C) 2018 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+// This is still valid in script code and strict and non strict modes
+// This is valid as module code
+// https://tc39.github.io/ecma262/#sec-scripts-static-semantics-lexicallydeclarednames
+var smoosh; function smoosh() {}
diff --git a/test/language/module-code/dynamic-import/dynamic-import-module_FIXTURE.js b/test/language/module-code/dynamic-import/dynamic-import-module_FIXTURE.js
new file mode 100644
index 0000000000..ef3f4207cd
--- /dev/null
+++ b/test/language/module-code/dynamic-import/dynamic-import-module_FIXTURE.js
@@ -0,0 +1,4 @@
+// Copyright (C) 2018 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+export var x = 1;
diff --git a/test/language/module-code/dynamic-import/returns-promise.js b/test/language/module-code/dynamic-import/returns-promise.js
new file mode 100644
index 0000000000..e44f6e24eb
--- /dev/null
+++ b/test/language/module-code/dynamic-import/returns-promise.js
@@ -0,0 +1,53 @@
+// Copyright (C) 2018 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    ImportCall returns a promise
+esid: sec-import-call-runtime-semantics-evaluation
+info: |
+    Import Calls
+
+    Runtime Semantics: Evaluation
+    
+    ImportCall : import(AssignmentExpression)
+    
+    1. Let referencingScriptOrModule be ! GetActiveScriptOrModule().
+    2. Let argRef be the result of evaluating AssignmentExpression.
+    3. Let specifier be ? GetValue(argRef).
+    4. Let promiseCapability be ! NewPromiseCapability(%Promise%).
+    5. Let specifierString be ToString(specifier).
+    6. IfAbruptRejectPromise(specifierString, promiseCapability).
+    7. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability).
+    8. Return promiseCapability.[[Promise]].
+features: [dynamic-import]
+includes: [fnGlobalObject.js]
+---*/
+
+const originalPromise = Promise;
+
+fnGlobalObject().Promise = function() {
+    throw "This should not be called";
+};
+
+const p = import('./dynamic-import-module_FIXTURE.js');
+
+assert.sameValue(p.constructor, originalPromise, 'constructor is %Promise%');
+assert.sameValue(Object.getPrototypeOf(p), originalPromise.prototype, 'prototype is %PromisePrototype%');
+assert.sameValue(p.then, originalPromise.prototype.then, 'preserves the original `then` method');
+assert.sameValue(p.catch, originalPromise.prototype.catch, 'preserves the original `catch` method');
+assert.sameValue(p.finally, originalPromise.prototype.finally, 'preserves the original `finally` method');
+
+assert.sameValue(
+    Object.prototype.hasOwnProperty.call(p, 'then'), false,
+    'returned promise has no own property then'
+);
+
+assert.sameValue(
+    Object.prototype.hasOwnProperty.call(p, 'catch'), false,
+    'returned promise has no own property catch'
+);
+
+assert.sameValue(
+    Object.prototype.hasOwnProperty.call(p, 'finally'), false,
+    'returned promise has no own property finally'
+);
diff --git a/test/language/module-code/dynamic-import/usage/module-code_FIXTURE.js b/test/language/module-code/dynamic-import/usage/module-code_FIXTURE.js
new file mode 100644
index 0000000000..96b0503d95
--- /dev/null
+++ b/test/language/module-code/dynamic-import/usage/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