Skip to content

Commit

Permalink
Add tests for Source Phase Imports (#3980)
Browse files Browse the repository at this point in the history
  • Loading branch information
legendecas authored Jun 27, 2024
1 parent c3a326a commit 8a2229c
Show file tree
Hide file tree
Showing 284 changed files with 10,329 additions and 26 deletions.
7 changes: 7 additions & 0 deletions INTERPRETING.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ properties of the global scope prior to test execution.
- **`sleep`** - a function that takes a millisecond argument and
sleeps the execution for approximately that duration.
- **`monotonicNow`** - a function that returns a value that conforms to [`DOMHighResTimeStamp`][] and is produced in such a way that its semantics conform to **[Monotonic Clock][]**.
- **`AbstractModuleSource`** - a reference to the `%AbstractModuleSource%` constructor which does not appear as a property of the global object.

In addition, consumers may choose to override any of [the functions defined by test harness files](https://github.com/tc39/test262/blob/HEAD/CONTRIBUTING.md#test-environment) as they see fit. See [the documentation on handling errors and negative test cases](https://github.com/tc39/test262/blob/HEAD/CONTRIBUTING.md#handling-errors-and-negative-test-cases) for a useful example of this.

Expand Down Expand Up @@ -160,6 +161,12 @@ located at `test/language/import/nested/dep.js`.

Files bearing a name ending in `.json` are intended to be interpreted as JSON.

Implementers should resolve the specifier `<module source>` to a module that
provides a valid [Module Source](https://tc39.es/proposal-source-phase-imports/#sec-module-source-objects),
such as a [WebAssembly module](https://webassembly.github.io/esm-integration/js-api/index.html#webassembly-module-record).
Tests use `<module source>` specifier are guarded with a feature flag
`source-phase-imports-module-source`.

### Staging

Tests in the `test/staging/` folder are expected to be executed just like all the other tests, in order to promote interoperability as soon as possible.
Expand Down
6 changes: 6 additions & 0 deletions features.txt
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,12 @@ explicit-resource-management
# https://github.com/tc39/proposal-float16array
Float16Array

# Source Phase Imports
## https://github.com/tc39/proposal-source-phase-imports
source-phase-imports
## test262 special specifier
source-phase-imports-module-source

## Standard language features
#
# Language features that have been included in a published version of the
Expand Down
25 changes: 25 additions & 0 deletions src/assignment-target-type/importcall-source.case
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (C) 2024 Chengzhong Wu. All rights reserved.
// Copyright (C) 2020 Rick Waldron. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-static-semantics-static-semantics-assignmenttargettype
desc: >
Static Semantics AssignmentTargetType, Return invalid.
info: |
ImportCall
Static Semantics AssignmentTargetType, Return invalid.
template: invalid
flags: [module]
features: [source-phase-imports]
negative:
phase: parse
type: SyntaxError
---*/

//- assignmenttarget
import.source()
//- operator
=
//- value
1
15 changes: 15 additions & 0 deletions src/dynamic-import/import-call-unknown.case
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright (C) 2024 Chengzhong Wu. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
desc: It's a SyntaxError on unknown import call
template: syntax/invalid
info: |
ImportCall[Yield, Await] :
import ( AssignmentExpression[+In, ?Yield, ?Await] )
import . source ( AssignmentExpression[+In, ?Yield, ?Await] )
features: [source-phase-imports]
---*/
//- import
import.UNKNOWN('./empty_FIXTURE.js')
//- teardown
/* The params region intentionally empty */
16 changes: 16 additions & 0 deletions src/dynamic-import/import-source-assignment-expr-not-optional.case
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright (C) 2024 Chengzhong Wu. All rights reserved.
// 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: It's a SyntaxError if AssignmentExpression is omitted
template: syntax/invalid
info: |
ImportCall[Yield, Await] :
import . source ( AssignmentExpression[+In, ?Yield, ?Await] )
features: [source-phase-imports]
---*/
//- import
import.source()
//- teardown
/* The params region intentionally empty */
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright (C) 2024 Chengzhong Wu. All rights reserved.
// 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: Calling import.source('')
template: syntax/valid
features: [source-phase-imports, source-phase-imports-module-source]
---*/

//- import
import.source('<module source>')
18 changes: 18 additions & 0 deletions src/dynamic-import/import-source-no-new-call-expression.case
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright (C) 2024 Chengzhong Wu. 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: ImportCall is a CallExpression, it can't be preceded by the new keyword
template: syntax/invalid
info: |
CallExpression:
ImportCall

ImportCall :
import . source ( AssignmentExpression[+In, ?Yield, ?Await] )

features: [source-phase-imports, source-phase-imports-module-source]
---*/

//- import
new import.source('<module source>')
22 changes: 22 additions & 0 deletions src/dynamic-import/import-source-no-rest-param.case
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (C) 2024 Chengzhong Wu. 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: ImportCall is not extensible - no rest parameter
template: syntax/invalid
info: |
ImportCall :
import . source ( AssignmentExpression[+In, ?Yield] )

Forbidden Extensions

- ImportCall must not be extended.

This production doesn't allow the following production from ArgumentsList:

... AssignmentExpression
features: [source-phase-imports, source-phase-imports-module-source]
---*/

//- import
import.source(...['<module source>'])
16 changes: 16 additions & 0 deletions src/dynamic-import/import-source-script-code-valid.case
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright (C) 2024 Chengzhong Wu. 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: import.source() can be used in script code
template: syntax/valid
features: [source-phase-imports, source-phase-imports-module-source]
---*/

//- 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.source('<module source>')
38 changes: 38 additions & 0 deletions src/dynamic-import/import-source-source-text-module.case
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (C) 2024 Chengzhong Wu. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
desc: >
GetModuleSource of SourceTextModule always returns an abrupt completion.
esid: sec-moduleevaluation
info: |
16.2.1.7.2 GetModuleSource ( )
Source Text Module Record provides a GetModuleSource implementation that always returns an abrupt completion indicating that a source phase import is not available.
1. Throw a ReferenceError exception.

Import Calls

Runtime Semantics: Evaluation

ImportCall : import . source ( AssignmentExpression )
1. Return ? EvaluateImportCall(AssignmentExpression, source).

13.3.10.1.1 EvaluateImportCall ( specifierExpression, phase )
1. Let referrer be GetActiveScriptOrModule().
2. If referrer is null, set referrer to the current Realm Record.
3. Let specifierRef be ? Evaluation of specifierExpression.
4. Let specifier be ? GetValue(specifierRef).
5. Let promiseCapability be ! NewPromiseCapability(%Promise%).
6. Let specifierString be Completion(ToString(specifier)).
7. IfAbruptRejectPromise(specifierString, promiseCapability).
8. Let moduleRequest be a new ModuleRequest Record { [[Specifier]]: specifierString, [[Phase]]: phase }.
9. Perform HostLoadImportedModule(referrer, moduleRequest, empty, promiseCapability).
10. Return promiseCapability.[[Promise]].

template: catch
features: [source-phase-imports]
---*/

//- import
import.source('./empty_FIXTURE.js')
//- body
assert.sameValue(error.name, 'ReferenceError');
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright (C) 2024 Chengzhong Wu. All rights reserved.
// 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 . source ( AssignmentExpression )
1. Return ? EvaluateImportCall(AssignmentExpression, source).

13.3.10.1.1 EvaluateImportCall ( specifierExpression, phase )
1. Let referrer be GetActiveScriptOrModule().
2. If referrer is null, set referrer to the current Realm Record.
3. Let specifierRef be ? Evaluation of specifierExpression.
4. Let specifier be ? GetValue(specifierRef).
5. Let promiseCapability be ! NewPromiseCapability(%Promise%).
6. Let specifierString be Completion(ToString(specifier)).
7. IfAbruptRejectPromise(specifierString, promiseCapability).
8. Let moduleRequest be a new ModuleRequest Record { [[Specifier]]: specifierString, [[Phase]]: phase }.
9. Perform HostLoadImportedModule(referrer, moduleRequest, empty, promiseCapability).
10. Return promiseCapability.[[Promise]].
template: catch
features: [source-phase-imports]
---*/

//- setup
const obj = {
toString() {
throw 'custom error';
}
};

//- import
import.source(obj)
//- body
assert.sameValue(error, 'custom error');
50 changes: 50 additions & 0 deletions src/dynamic-import/import-source-specifier-tostring.case
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright (C) 2024 Chengzhong Wu. All rights reserved.
// 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 . source ( AssignmentExpression )
1. Return ? EvaluateImportCall(AssignmentExpression, source).

13.3.10.1.1 EvaluateImportCall ( specifierExpression, phase )
1. Let referrer be GetActiveScriptOrModule().
2. If referrer is null, set referrer to the current Realm Record.
3. Let specifierRef be ? Evaluation of specifierExpression.
4. Let specifier be ? GetValue(specifierRef).
5. Let promiseCapability be ! NewPromiseCapability(%Promise%).
6. Let specifierString be Completion(ToString(specifier)).
7. IfAbruptRejectPromise(specifierString, promiseCapability).
8. Let moduleRequest be a new ModuleRequest Record { [[Specifier]]: specifierString, [[Phase]]: phase }.
9. Perform HostLoadImportedModule(referrer, moduleRequest, empty, promiseCapability).
10. Return promiseCapability.[[Promise]].

16.2.1.7.2 GetModuleSource ( )
Source Text Module Record provides a GetModuleSource implementation that always returns an abrupt completion indicating that a source phase import is not available.
1. Throw a ReferenceError exception.

template: catch
features: [source-phase-imports]
---*/

//- setup
// The following case is equivalent of the call of:
// import.source('./empty_FIXTURE.js')

const obj = {
toString() {
return './empty_FIXTURE.js';
}
};

//- import
import.source(obj)
//- body
assert.sameValue(error.name, 'ReferenceError');
15 changes: 15 additions & 0 deletions src/dynamic-import/typeof-import-call-source-property.case
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright (C) 2024 Chengzhong Wu. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
desc: It's a SyntaxError on unexpected import source property
template: syntax/invalid
info: |
ImportCall[Yield, Await] :
import ( AssignmentExpression[+In, ?Yield, ?Await] )
import . source ( AssignmentExpression[+In, ?Yield, ?Await] )
features: [source-phase-imports]
---*/
//- import
typeof import.source.UNKNOWN
//- teardown
/* The params region intentionally empty */
14 changes: 14 additions & 0 deletions src/dynamic-import/typeof-import-source.case
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright (C) 2024 Chengzhong Wu. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
desc: It's a SyntaxError if '()' is omitted
template: syntax/invalid
info: |
ImportCall[Yield, Await] :
import . source ( AssignmentExpression[+In, ?Yield, ?Await] )
features: [source-phase-imports]
---*/
//- import
typeof import.source
//- teardown
/* The params region intentionally empty */
13 changes: 13 additions & 0 deletions src/dynamic-import/typeof-import.case
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (C) 2024 Chengzhong Wu. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
desc: It's a SyntaxError if '()' is omitted
template: syntax/invalid
info: |
ImportCall[Yield, Await] :
import . source ( AssignmentExpression[+In, ?Yield, ?Await] )
---*/
//- import
typeof import
//- teardown
/* The params region intentionally empty */
21 changes: 21 additions & 0 deletions test/built-ins/AbstractModuleSource/length.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (C) 2024 Chengzhong Wu. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-properties-of-the-%abstractmodulesource%25-intrinsic-object
description: >
%AbstractModuleSource%.length property descriptor
info: |
28.1.1.1 %AbstractModuleSource% ( )
includes: [propertyHelper.js]
features: [source-phase-imports]
flags: [module]
---*/

assert.sameValue(typeof $262.AbstractModuleSource, 'function');
verifyProperty($262.AbstractModuleSource, 'length', {
value: 0,
writable: false,
enumerable: false,
configurable: true
});
24 changes: 24 additions & 0 deletions test/built-ins/AbstractModuleSource/name.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright (C) 2024 Chengzhong Wu. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-properties-of-the-%abstractmodulesource%25-intrinsic-object
description: >
%AbstractModuleSource%.name property descriptor
info: |
The %AbstractModuleSource% intrinsic object has a "name" property whose value is "AbstractModuleSource".
Unless otherwise specified, the name property of a built-in function
object, if it exists, has the attributes { [[Writable]]: false,
[[Enumerable]]: false, [[Configurable]]: true }.
includes: [propertyHelper.js]
features: [source-phase-imports]
flags: [module]
---*/

assert.sameValue(typeof $262.AbstractModuleSource, 'function');
verifyProperty($262.AbstractModuleSource, 'name', {
value: 'AbstractModuleSource',
writable: false,
enumerable: false,
configurable: true
});
Loading

0 comments on commit 8a2229c

Please sign in to comment.