-
Notifications
You must be signed in to change notification settings - Fork 471
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: adding tests for optional chaining proposal #2212
Changes from all commits
8d67614
2a26709
1ecf3ee
12d1af1
9d53a4b
13d9cb0
4e81676
bc393df
129acbb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// Copyright 2019 Google, Inc. All rights reserved. | ||
// This code is governed by the BSD license found in the LICENSE file. | ||
/*--- | ||
esid: prod-OptionalExpression | ||
description: > | ||
optional chain on call expression | ||
info: | | ||
Left-Hand-Side Expressions | ||
OptionalExpression: | ||
CallExpression OptionalChain | ||
features: [optional-chaining] | ||
---*/ | ||
|
||
function fn () { | ||
return {a: 33}; | ||
}; | ||
|
||
// CallExpression Arguments | ||
assert.sameValue(33, fn()?.a); | ||
assert.sameValue(undefined, fn()?.b); | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// Copyright 2019 Google, Inc. All rights reserved. | ||
// This code is governed by the BSD license found in the LICENSE file. | ||
/*--- | ||
esid: prod-OptionalExpression | ||
description: > | ||
template string passed to tail position of optional chain | ||
info: | | ||
Static Semantics: Early Errors | ||
OptionalChain: | ||
?.TemplateLiteral | ||
OptionalChain TemplateLiteral | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please add the error part: |
||
features: [optional-chaining] | ||
negative: | ||
type: SyntaxError | ||
phase: parse | ||
---*/ | ||
|
||
$DONOTEVALUATE(); | ||
|
||
const a = {fn() {}}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this can be a simple |
||
|
||
// This production exists in order to prevent automatic semicolon | ||
// insertion rules. | ||
a?.fn | ||
`hello` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For a follow up PR: we are missing tests for the a?.`hello`
// and
a?.
`hello` Also verify this is valid syntax: `foo`?.bar |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// Copyright 2019 Google, Inc. All rights reserved. | ||
// This code is governed by the BSD license found in the LICENSE file. | ||
/*--- | ||
esid: prod-OptionalExpression | ||
description: > | ||
template string passed to tail position of optional chain | ||
info: | | ||
Static Semantics: Early Errors | ||
OptionalChain: | ||
?.TemplateLiteral | ||
OptionalChain TemplateLiteral | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please add the error part: It is a Syntax Error if any code matches this production. |
||
features: [optional-chaining] | ||
negative: | ||
type: SyntaxError | ||
phase: parse | ||
---*/ | ||
|
||
$DONOTEVALUATE(); | ||
|
||
const a = {fn() {}}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. name can be simplified here as well. |
||
|
||
// This production exists in order to prevent automatic semicolon | ||
// insertion rules. | ||
a?.fn`hello`; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
// Copyright 2019 Google, Inc. All rights reserved. | ||
// This code is governed by the BSD license found in the LICENSE file. | ||
/*--- | ||
esid: prod-OptionalExpression | ||
description: > | ||
optional chain on member expression | ||
info: | | ||
Left-Hand-Side Expressions | ||
OptionalExpression: | ||
MemberExpression OptionalChain | ||
features: [optional-chaining] | ||
---*/ | ||
|
||
// PrimaryExpression | ||
// IdentifierReference | ||
|
||
const arr = [10, 11]; | ||
const fn = (arg1, arg2) => { | ||
return arg1 + arg2; | ||
} | ||
const i = 0; | ||
const obj = { | ||
a: 'hello', | ||
b: {val: 13}, | ||
c(arg1) { | ||
return arg1 * 2; | ||
}, | ||
arr: [11, 12] | ||
}; | ||
|
||
// OptionalChain: ?.[Expression] | ||
assert.sameValue(11, arr?.[i + 1]); | ||
|
||
// OptionalChain: ?.IdentifierName | ||
assert.sameValue('hello', obj?.a); | ||
|
||
// OptionalChain: ?.Arguments | ||
assert.sameValue(30, fn?.(10, 20)); | ||
|
||
// OptionalChain: OptionalChain [Expression] | ||
assert.sameValue(12, obj?.arr[i + 1]); | ||
assert.throws(TypeError, function() { | ||
obj?.d[i + 1]; | ||
}); | ||
|
||
// OptionalChain: OptionalChain .IdentifierName | ||
assert.sameValue(13, obj?.b.val); | ||
assert.throws(TypeError, function() { | ||
obj?.d.e; | ||
}); | ||
|
||
// OptionalChain: OptionalChain Arguments | ||
assert.sameValue(20, obj?.c(10)); | ||
assert.throws(TypeError, function() { | ||
obj?.d(); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// Copyright 2019 Google, Inc. All rights reserved. | ||
// This code is governed by the BSD license found in the LICENSE file. | ||
/*--- | ||
esid: prod-OptionalExpression | ||
description: > | ||
optional chain on recursive optional expression | ||
info: | | ||
Left-Hand-Side Expressions | ||
OptionalExpression: | ||
OptionalExpression OptionalChain | ||
features: [optional-chaining] | ||
---*/ | ||
|
||
const obj = { | ||
a: { | ||
b: 22 | ||
} | ||
}; | ||
|
||
function fn () { | ||
return {}; | ||
} | ||
|
||
// MemberExpression | ||
assert.sameValue(22, (obj?.a)?.b); | ||
// CallExpression | ||
assert.sameValue(undefined, (fn()?.a)?.b); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// Copyright 2019 Google, Inc. All rights reserved. | ||
// This code is governed by the BSD license found in the LICENSE file. | ||
/*--- | ||
esid: prod-OptionalExpression | ||
description: > | ||
ternary operation with decimal does not evaluate as optional chain | ||
info: | | ||
Punctuators | ||
OptionalChainingPunctuator:: | ||
?.[lookahead ∉ DecimalDigit] | ||
features: [optional-chaining] | ||
---*/ | ||
|
||
const value = true ?.30 : false; | ||
assert.sameValue(.30, value); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// Copyright 2019 Google, Inc. All rights reserved. | ||
// This code is governed by the BSD license found in the LICENSE file. | ||
/*--- | ||
esid: prod-OptionalExpression | ||
description: > | ||
accessing optional value on undefined or null returns undefined. | ||
info: | | ||
If baseValue is undefined or null, then | ||
Return undefined. | ||
features: [optional-chaining] | ||
---*/ | ||
|
||
const nul = null; | ||
const undf = undefined; | ||
assert.sameValue(undefined, nul?.a); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. for a follow up: var x = 0;
var y = null?.[(function() { x += 1 }())];
// assert value of x to verify if the `[Expression]` has got evaluated
// assert y is undefined. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh! you did that in |
||
assert.sameValue(undefined, undf?.b); | ||
bcoe marked this conversation as resolved.
Show resolved
Hide resolved
|
||
assert.sameValue(undefined, null?.a); | ||
assert.sameValue(undefined, undefined?.b); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
// Copyright 2019 Google, Inc. All rights reserved. | ||
// This code is governed by the BSD license found in the LICENSE file. | ||
/*--- | ||
esid: prod-OptionalExpression | ||
description: > | ||
demonstrate syntax-based short-circuiting. | ||
info: | | ||
If the expression on the LHS of ?. evaluates to null/undefined, the RHS is | ||
not evaluated | ||
features: [optional-chaining] | ||
---*/ | ||
|
||
const a = undefined; | ||
let x = 1; | ||
|
||
a?.[++x] // short-circuiting. | ||
a?.b.c(++x).d; // long short-circuiting. | ||
bcoe marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
undefined?.[++x] // short-circuiting. | ||
undefined?.b.c(++x).d; // long short-circuiting. | ||
|
||
assert.sameValue(1, x); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
|
||
// Copyright 2019 Google, Inc. All rights reserved. | ||
// This code is governed by the BSD license found in the LICENSE file. | ||
/*--- | ||
esid: prod-OptionalExpression | ||
description: > | ||
an optional expression cannot be target of assignment | ||
info: | | ||
Static Semantics: IsValidSimpleAssignmentTarget | ||
LeftHandSideExpression: | ||
OptionalExpression | ||
Return false. | ||
features: [optional-chaining] | ||
negative: | ||
type: SyntaxError | ||
phase: parse | ||
---*/ | ||
|
||
$DONOTEVALUATE(); | ||
|
||
const obj = {}; | ||
|
||
obj?.a = 33; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nice! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in a follow up PR, we should expand these to other types and checking property existence:
Currently the CallExpression evaluates to:
a
Missing:
a. false
b. 0
c. ''
d. undefined // different behavior
e. null // same as undefined
a. true
b. 1
c. NaN
d. 'undefined'
e. Symbol
This test itself is good enough as a syntax test, these expansions are more useful for further evaluation of the results.