From 3d0c2037c3d7d4baf309220f09e7ce83eeb8f0ee Mon Sep 17 00:00:00 2001 From: bcoe Date: Sun, 17 Nov 2019 21:11:24 -0800 Subject: [PATCH 1/2] feat(optional-chaining): add tests for IterationStatement --- .../iteration-statement-do.js | 18 ++++++++++ .../iteration-statement-for-await-of.js | 34 +++++++++++++++++++ .../iteration-statement-for-in.js | 22 ++++++++++++ .../iteration-statement-for-of-type-error.js | 18 ++++++++++ .../iteration-statement-for.js | 27 +++++++++++++++ .../iteration-statement-while.js | 18 ++++++++++ 6 files changed, 137 insertions(+) create mode 100644 test/language/expressions/optional-chaining/iteration-statement-do.js create mode 100644 test/language/expressions/optional-chaining/iteration-statement-for-await-of.js create mode 100644 test/language/expressions/optional-chaining/iteration-statement-for-in.js create mode 100644 test/language/expressions/optional-chaining/iteration-statement-for-of-type-error.js create mode 100644 test/language/expressions/optional-chaining/iteration-statement-for.js create mode 100644 test/language/expressions/optional-chaining/iteration-statement-while.js diff --git a/test/language/expressions/optional-chaining/iteration-statement-do.js b/test/language/expressions/optional-chaining/iteration-statement-do.js new file mode 100644 index 0000000000..5a82cc23cd --- /dev/null +++ b/test/language/expressions/optional-chaining/iteration-statement-do.js @@ -0,0 +1,18 @@ +// Copyright 2019 Google, LLC. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: prod-OptionalExpression +description: > + optional chain in test portion of do while statement +info: | + IterationStatement + do Statement while (OptionalExpression) +features: [optional-chaining] +---*/ +let count = 0; +const obj = {a: true}; +do { + count++; + break; +} while (obj?.a); +assert.sameValue(1, count); diff --git a/test/language/expressions/optional-chaining/iteration-statement-for-await-of.js b/test/language/expressions/optional-chaining/iteration-statement-for-await-of.js new file mode 100644 index 0000000000..e7b9ebde8b --- /dev/null +++ b/test/language/expressions/optional-chaining/iteration-statement-for-await-of.js @@ -0,0 +1,34 @@ +// Copyright 2019 Google, LLC. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: prod-OptionalExpression +description: > + optional chain RHS of for await statement +info: | + IterationStatement + for await (LeftHandSideExpression of AssignmentExpression) Statement +features: [optional-chaining] +---*/ +const obj = { + iterable: { + [Symbol.asyncIterator]() { + return { + i: 0, + next() { + if (this.i < 3) { + return Promise.resolve({ value: this.i++, done: false }); + } + return Promise.resolve({ done: true }); + } + }; + } + } +}; +async function checkAssertions() { + let count = 0; + for await (const num of obj?.iterable) { + count += num; + } + assert.sameValue(3, count); +} +checkAssertions().then($DONE, $DONE); diff --git a/test/language/expressions/optional-chaining/iteration-statement-for-in.js b/test/language/expressions/optional-chaining/iteration-statement-for-in.js new file mode 100644 index 0000000000..2823b8053b --- /dev/null +++ b/test/language/expressions/optional-chaining/iteration-statement-for-in.js @@ -0,0 +1,22 @@ +// Copyright 2019 Google, LLC. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: prod-OptionalExpression +description: > + optional chain in test portion of do while statement +info: | + IterationStatement + for (LeftHandSideExpression in Expression) Statement +features: [optional-chaining] +---*/ +const obj = { + inner: { + a: 1, + b: 2 + } +}; +let str = ''; +for (const key in obj?.inner) { + str += key; +} +assert.sameValue('ab', str); diff --git a/test/language/expressions/optional-chaining/iteration-statement-for-of-type-error.js b/test/language/expressions/optional-chaining/iteration-statement-for-of-type-error.js new file mode 100644 index 0000000000..080d19c3a9 --- /dev/null +++ b/test/language/expressions/optional-chaining/iteration-statement-for-of-type-error.js @@ -0,0 +1,18 @@ +// Copyright 2019 Google, LLC. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: prod-OptionalExpression +description: > + optional chain returning undefined in RHS of for of statement +info: | + IterationStatement + for (LeftHandSideExpression of Expression) Statement +features: [optional-chaining] +---*/ + +assert.throws(TypeError, function() { + const obj = undefined; + for (const key of obj?.a) { + str += key; + } +}); diff --git a/test/language/expressions/optional-chaining/iteration-statement-for.js b/test/language/expressions/optional-chaining/iteration-statement-for.js new file mode 100644 index 0000000000..34e6b8e3e1 --- /dev/null +++ b/test/language/expressions/optional-chaining/iteration-statement-for.js @@ -0,0 +1,27 @@ +// Copyright 2019 Google, LLC. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: prod-OptionalExpression +description: > + optional chain in init/test/update of for statement +info: | + IterationStatement + for (Expression; Expression; Expression) Statement +features: [optional-chaining] +---*/ + +// OptionalExpression in test. +let count; +const obj = {a: true}; +for (count = 0; obj?.a; count++) { + if (count > 0) break; +} +assert.sameValue(1, count); + +// OptionalExpression in init/test/update. +let count2 = 0; +const obj2 = undefined; +for (obj?.a; obj2?.a; obj?.a) { + count2++; +} +assert.sameValue(0, count2); diff --git a/test/language/expressions/optional-chaining/iteration-statement-while.js b/test/language/expressions/optional-chaining/iteration-statement-while.js new file mode 100644 index 0000000000..80fffa9296 --- /dev/null +++ b/test/language/expressions/optional-chaining/iteration-statement-while.js @@ -0,0 +1,18 @@ +// Copyright 2019 Google, LLC. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: prod-OptionalExpression +description: > + optional chain in test portion of while statement +info: | + IterationStatement + while (Expression) Statement +features: [optional-chaining] +---*/ +let count = 0; +const obj = {a: true}; +while (obj?.a) { + count++; + break; +} +assert.sameValue(1, count); From 5babea278043dfc6029726769653b8c3a733272d Mon Sep 17 00:00:00 2001 From: bcoe Date: Mon, 18 Nov 2019 20:44:34 -0800 Subject: [PATCH 2/2] chore: added a few more examples based on code review --- .../iteration-statement-for-await-of.js | 1 + .../iteration-statement-for-of-type-error.js | 18 ++++++++++---- .../iteration-statement-for.js | 24 +++++++++++++++---- 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/test/language/expressions/optional-chaining/iteration-statement-for-await-of.js b/test/language/expressions/optional-chaining/iteration-statement-for-await-of.js index e7b9ebde8b..6d414965ab 100644 --- a/test/language/expressions/optional-chaining/iteration-statement-for-await-of.js +++ b/test/language/expressions/optional-chaining/iteration-statement-for-await-of.js @@ -8,6 +8,7 @@ info: | IterationStatement for await (LeftHandSideExpression of AssignmentExpression) Statement features: [optional-chaining] +flags: [async] ---*/ const obj = { iterable: { diff --git a/test/language/expressions/optional-chaining/iteration-statement-for-of-type-error.js b/test/language/expressions/optional-chaining/iteration-statement-for-of-type-error.js index 080d19c3a9..3cd18cd48f 100644 --- a/test/language/expressions/optional-chaining/iteration-statement-for-of-type-error.js +++ b/test/language/expressions/optional-chaining/iteration-statement-for-of-type-error.js @@ -11,8 +11,18 @@ features: [optional-chaining] ---*/ assert.throws(TypeError, function() { - const obj = undefined; - for (const key of obj?.a) { - str += key; - } + for (const key of {}?.a) ; +}); + +assert.throws(TypeError, function() { + for (const key of {}?.a) {} +}); + +const obj = undefined; +assert.throws(TypeError, function() { + for (const key of obj?.a) {} +}); + +assert.throws(TypeError, function() { + for (const key of obj?.a); }); diff --git a/test/language/expressions/optional-chaining/iteration-statement-for.js b/test/language/expressions/optional-chaining/iteration-statement-for.js index 34e6b8e3e1..c6d78a3181 100644 --- a/test/language/expressions/optional-chaining/iteration-statement-for.js +++ b/test/language/expressions/optional-chaining/iteration-statement-for.js @@ -16,12 +16,28 @@ const obj = {a: true}; for (count = 0; obj?.a; count++) { if (count > 0) break; } -assert.sameValue(1, count); +assert.sameValue(count, 1); // OptionalExpression in init/test/update. let count2 = 0; const obj2 = undefined; -for (obj?.a; obj2?.a; obj?.a) { - count2++; + +for (obj?.a; obj2?.a; obj?.a) { count2++; } +assert.sameValue(count2, 0); + +for (obj?.a; undefined?.a; obj?.a) { count2++; } +assert.sameValue(count2, 0); + +// Short-circuiting +let touched = 0; +const obj3 = { + get a() { + count++; + return undefined; // explicit for clarity + } +}; +for (count = 0; true; obj3?.a?.[touched++]) { + if (count > 0) { break; } } -assert.sameValue(0, count2); +assert.sameValue(count, 1); +assert.sameValue(touched, 0);