From 73409cea4e85b83d1483ea73904fed6e03845207 Mon Sep 17 00:00:00 2001 From: Leonardo Balter Date: Tue, 21 Jul 2015 21:20:08 -0400 Subject: [PATCH] Add tests for default parameters --- .../default-parameters/call-define-values.js | 44 +++++++++++++ .../call-returns-reference-error.js | 13 ++++ .../default-parameters/class-definitions.js | 21 +++++++ ...eters-always-provide-unmapped-arguments.js | 50 +++++++++++++++ .../default-parameters/destructuring.js | 17 ++++++ .../function-constructor.js | 13 ++++ .../default-parameters/function-length.js | 26 ++++++++ .../language/default-parameters/generators.js | 24 ++++++++ .../default-parameters/method-definitions.js | 14 +++++ .../param-ref-initialized.js | 14 +++++ .../param-ref-uninitialized.js | 24 ++++++++ .../replace-default-values.js | 61 +++++++++++++++++++ .../default-parameters/rest-parameters.js | 10 +++ .../returns-abrupt-from-property-value.js | 22 +++++++ test/language/default-parameters/scope.js | 50 +++++++++++++++ ...r-on-duplicates-on-function-declaration.js | 16 +++++ ...or-on-duplicates-on-function-expression.js | 16 +++++ .../variable-initial-value-as-parameter.js | 40 ++++++++++++ .../variable-initial-value-undefined.js | 38 ++++++++++++ 19 files changed, 513 insertions(+) create mode 100644 test/language/default-parameters/call-define-values.js create mode 100644 test/language/default-parameters/call-returns-reference-error.js create mode 100644 test/language/default-parameters/class-definitions.js create mode 100644 test/language/default-parameters/default-parameters-always-provide-unmapped-arguments.js create mode 100644 test/language/default-parameters/destructuring.js create mode 100644 test/language/default-parameters/function-constructor.js create mode 100644 test/language/default-parameters/function-length.js create mode 100644 test/language/default-parameters/generators.js create mode 100644 test/language/default-parameters/method-definitions.js create mode 100644 test/language/default-parameters/param-ref-initialized.js create mode 100644 test/language/default-parameters/param-ref-uninitialized.js create mode 100644 test/language/default-parameters/replace-default-values.js create mode 100644 test/language/default-parameters/rest-parameters.js create mode 100644 test/language/default-parameters/returns-abrupt-from-property-value.js create mode 100644 test/language/default-parameters/scope.js create mode 100644 test/language/default-parameters/syntaxerror-on-duplicates-on-function-declaration.js create mode 100644 test/language/default-parameters/syntaxerror-on-duplicates-on-function-expression.js create mode 100644 test/language/default-parameters/variable-initial-value-as-parameter.js create mode 100644 test/language/default-parameters/variable-initial-value-undefined.js diff --git a/test/language/default-parameters/call-define-values.js b/test/language/default-parameters/call-define-values.js new file mode 100644 index 0000000000..1a74cadebf --- /dev/null +++ b/test/language/default-parameters/call-define-values.js @@ -0,0 +1,44 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.2.12 +description: > + Function call define default values to arguments +info: > + 9.2.12 FunctionDeclarationInstantiation(func, argumentsList) + + 24. If hasDuplicates is true, then + ... + 25. Else, + a. Let formalStatus be IteratorBindingInitialization for formals with + iteratorRecord and env as arguments. + + ES6 13.3.3.6 Runtime Semantics: IteratorBindingInitialization + + SingleNameBinding : BindingIdentifier Initializeropt + + ... + 6. If Initializer is present and v is undefined, then + a. Let defaultValue be the result of evaluating Initializer. + b. Let v be GetValue(defaultValue). + ... +---*/ + +var results; + +var o = {}; + +function fn(a = 1, b = null, c = o, d) { + return [a, b, c, d]; +} + +results = fn(); + +assert.sameValue(results[0], 1, 'apply default values #1'); +assert.sameValue(results[1], null, 'apply default values #2'); +assert.sameValue(results[2], o, 'apply default values #3'); + +assert.sameValue( + results[3], undefined, + 'Parameters without defaults after default parameters defaults to undefined' +); diff --git a/test/language/default-parameters/call-returns-reference-error.js b/test/language/default-parameters/call-returns-reference-error.js new file mode 100644 index 0000000000..2a6d9176cb --- /dev/null +++ b/test/language/default-parameters/call-returns-reference-error.js @@ -0,0 +1,13 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 13.3.3.7 +description: > + Throws a ReferenceError from a unsolvable reference as the default parameter. +---*/ + +function fn(a = unresolvableReference) {} + +assert.throws(ReferenceError, function() { + fn(); +}); diff --git a/test/language/default-parameters/class-definitions.js b/test/language/default-parameters/class-definitions.js new file mode 100644 index 0000000000..bb3ae02f24 --- /dev/null +++ b/test/language/default-parameters/class-definitions.js @@ -0,0 +1,21 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 14.5 +description: Set default parameters on class definitions +---*/ + +class C { + constructor(a = 1) { + this.a = a; + } + + m(x = 2) { + return x; + } +} + +var o = new C(); + +assert.sameValue(o.a, 1); +assert.sameValue(o.m(), 2); diff --git a/test/language/default-parameters/default-parameters-always-provide-unmapped-arguments.js b/test/language/default-parameters/default-parameters-always-provide-unmapped-arguments.js new file mode 100644 index 0000000000..54ac40a111 --- /dev/null +++ b/test/language/default-parameters/default-parameters-always-provide-unmapped-arguments.js @@ -0,0 +1,50 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.2.12 +description: > + Provide unmapped `arguments` if any parameter has a default value initializer. +info: > + 9.2.12 FunctionDeclarationInstantiation(func, argumentsList) + + 22. If argumentsObjectNeeded is true, then + a. If strict is true or if simpleParameterList is false, then + i. Let ao be CreateUnmappedArgumentsObject(argumentsList). + ... + d. If strict is true, then + ... + e. Else, + i. Let status be envRec.CreateMutableBinding("arguments"). +flags: [noStrict] +---*/ + +var _c; + +function fn(a, b = 1, c = 1, d = 1) { + a = false; + arguments[2] = false; + _c = c; + return arguments; +} + +var result = fn(42, undefined, 43); + +assert.sameValue( + result[0], 42, + 'unmapped `arguments` are not bound to their parameters values' +); + +assert.sameValue( + result[1], undefined, + 'unmapped `arguments` preserve the given arguments values' +); + +assert.sameValue( + _c, 43, + 'parameters names are not mapped to be bound' +); + +assert.sameValue( + Object.hasOwnProperty(result, '3'), false, + 'unmapped `arguments` will only contain values from the arguments list' +); diff --git a/test/language/default-parameters/destructuring.js b/test/language/default-parameters/destructuring.js new file mode 100644 index 0000000000..08b1c93d2c --- /dev/null +++ b/test/language/default-parameters/destructuring.js @@ -0,0 +1,17 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 13.3.3 +description: > + Destructuring values on default parameters. +---*/ + +function fn([a, b] = [1, 2], {c: c} = {c: 3}) { + return [a, b, c]; +} + +var results = fn(); + +assert.sameValue(results[0], 1); +assert.sameValue(results[1], 2); +assert.sameValue(results[2], 3); diff --git a/test/language/default-parameters/function-constructor.js b/test/language/default-parameters/function-constructor.js new file mode 100644 index 0000000000..44345a81d4 --- /dev/null +++ b/test/language/default-parameters/function-constructor.js @@ -0,0 +1,13 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 19.2.1.1 +description: > + Create new Function with default parameters +---*/ + +var fn = new Function('a = 42', 'b = "foo"', 'return [a, b]'); +var result = fn(); + +assert.sameValue(result[0], 42); +assert.sameValue(result[1], 'foo'); diff --git a/test/language/default-parameters/function-length.js b/test/language/default-parameters/function-length.js new file mode 100644 index 0000000000..c26f313a6e --- /dev/null +++ b/test/language/default-parameters/function-length.js @@ -0,0 +1,26 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 14.1.6 +description: > + Default parameters' effect on function length +info: > + Function length is counted by the non initialized parameters in the left. + + FormalsList : FormalParameter + + 1. If HasInitializer of FormalParameter is true return 0 + 2. Return 1. + + FormalsList : FormalsList , FormalParameter + + 1. Let count be the ExpectedArgumentCount of FormalsList. + 2. If HasInitializer of FormalsList is true or HasInitializer of + FormalParameter is true, return count. + 3. Return count+1. +---*/ + +assert.sameValue((function (x = 42) {}).length, 0); +assert.sameValue((function (x = 42, y) {}).length, 0); +assert.sameValue((function (x, y = 42) {}).length, 1); +assert.sameValue((function (x, y = 42, z) {}).length, 1); diff --git a/test/language/default-parameters/generators.js b/test/language/default-parameters/generators.js new file mode 100644 index 0000000000..b511d5f768 --- /dev/null +++ b/test/language/default-parameters/generators.js @@ -0,0 +1,24 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 14.4 +description: Set default parameters in generator functions +---*/ + +function *g(a = 1, b = 2, c = 3) { + var i = 0; + + while (i < 3) { + yield [a, b, c][i]; + i++; + } + + return 42; +} + +var iter = g(); + +assert.sameValue(iter.next().value, 1); +assert.sameValue(iter.next().value, 2); +assert.sameValue(iter.next().value, 3); +assert.sameValue(iter.next().done, true); diff --git a/test/language/default-parameters/method-definitions.js b/test/language/default-parameters/method-definitions.js new file mode 100644 index 0000000000..a0c859e677 --- /dev/null +++ b/test/language/default-parameters/method-definitions.js @@ -0,0 +1,14 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 14.3 +description: Set default parameters on method definitions +---*/ + +var o = { + m(a = 1, b = 2) { + return a + b; + } +}; + +assert.sameValue(o.m(), 3); diff --git a/test/language/default-parameters/param-ref-initialized.js b/test/language/default-parameters/param-ref-initialized.js new file mode 100644 index 0000000000..d03d8deb46 --- /dev/null +++ b/test/language/default-parameters/param-ref-initialized.js @@ -0,0 +1,14 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.2.12 +description: > + Parameters can refer to previous parameters +---*/ + +function fn(a = 42, b = a) { + return b; +} + +assert.sameValue(fn(), 42); +assert.sameValue(fn(17), 17); diff --git a/test/language/default-parameters/param-ref-uninitialized.js b/test/language/default-parameters/param-ref-uninitialized.js new file mode 100644 index 0000000000..8410f61e7d --- /dev/null +++ b/test/language/default-parameters/param-ref-uninitialized.js @@ -0,0 +1,24 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.2.12 +description: > + Parameters can't refer to not initialized parameters +---*/ + +function fn1(a = a) { + return a; +} + +assert.throws(ReferenceError, function() { + fn1(); +}); + + +function fn2(a = b, b = 42) { + return a; +} + +assert.throws(ReferenceError, function() { + fn2(); +}); diff --git a/test/language/default-parameters/replace-default-values.js b/test/language/default-parameters/replace-default-values.js new file mode 100644 index 0000000000..d1628d4a56 --- /dev/null +++ b/test/language/default-parameters/replace-default-values.js @@ -0,0 +1,61 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.2.12 +description: > + Replace default values, unless argument is undefined +info: > + 9.2.12 FunctionDeclarationInstantiation(func, argumentsList) + + 24. If hasDuplicates is true, then + ... + 25. Else, + a. Let formalStatus be IteratorBindingInitialization for formals with + iteratorRecord and env as arguments. + + ES6 13.3.3.6 Runtime Semantics: IteratorBindingInitialization + + SingleNameBinding : BindingIdentifier Initializeropt + + ... + 6. If Initializer is present and v is undefined, then + a. Let defaultValue be the result of evaluating Initializer. + b. Let v be GetValue(defaultValue). + ... +features: [Symbol] +---*/ + +function fn(a = 1, b = 2, c = 3) { + return [a, b, c]; +} + +var results = fn('', 'foo', 'undefined'); +assert.sameValue(results[0], '', 'empty string replace default value'); +assert.sameValue(results[1], 'foo', 'string replaces default value'); +assert.sameValue( + results[2], 'undefined', + '"undefined" string replaces default value' +); + +results = fn(0, 42, -Infinity); +assert.sameValue(results[0], 0, 'Number (0) replaces default value'); +assert.sameValue(results[1], 42, 'number replaces default value'); +assert.sameValue(results[2], -Infinity, '-Infinity replaces default value'); + +var o = {}; +var arr = []; +results = fn(o, arr, null); +assert.sameValue(results[0], o, 'object replaces default value'); +assert.sameValue(results[1], arr, 'array replaces default value'); +assert.sameValue(results[2], null, 'null replaces default value'); + +var s = Symbol(''); +results = fn(true, false, s); +assert.sameValue(results[0], true, 'boolean true replaces default value'); +assert.sameValue(results[1], false, 'boolean false replaces default value'); +assert.sameValue(results[2], s, 'Symbol replaces default value'); + +results = fn(undefined, NaN, undefined); +assert.sameValue(results[0], 1, 'undefined argument does not replace default'); +assert.sameValue(results[1], NaN, 'NaN replaces default value'); +assert.sameValue(results[2], 3, 'undefined argument does not replace default'); diff --git a/test/language/default-parameters/rest-parameters.js b/test/language/default-parameters/rest-parameters.js new file mode 100644 index 0000000000..9b63fab425 --- /dev/null +++ b/test/language/default-parameters/rest-parameters.js @@ -0,0 +1,10 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 14.1 +description: > + Rest parameters can not have a default +negative: SyntaxError +---*/ + +function fn(...args = [1]) {} diff --git a/test/language/default-parameters/returns-abrupt-from-property-value.js b/test/language/default-parameters/returns-abrupt-from-property-value.js new file mode 100644 index 0000000000..a19e82d5d9 --- /dev/null +++ b/test/language/default-parameters/returns-abrupt-from-property-value.js @@ -0,0 +1,22 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 13.3.3.7 +description: > + Return abrupt from a property value as a default argument. +---*/ + +var obj = {}; +Object.defineProperty(obj, 'err', { + get: function() { + throw new Test262Error(); + } +}); + +function fn(a = obj.err) { + return 42; +} + +assert.throws(Test262Error, function() { + fn(); +}); diff --git a/test/language/default-parameters/scope.js b/test/language/default-parameters/scope.js new file mode 100644 index 0000000000..6f5c442d92 --- /dev/null +++ b/test/language/default-parameters/scope.js @@ -0,0 +1,50 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.2.12 +description: > + Expressions as parameter default values share the top level context only. +info: > + 9.2.12 FunctionDeclarationInstantiation(func, argumentsList) + + ... + 27. If hasParameterExpressions is false, then + ... + 28. Else, + a. NOTE A separate Environment Record is needed to ensure that + closures created by expressions in the formal parameter list do + not have visibility of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv’s EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. +---*/ + +var x = 42; + +function fn1(a = x) { + return a; +} +assert.sameValue(fn1(), 42); + +function fn2(a = function() { return x; }) { + var x = 1; + + return a(); +} +assert.sameValue(fn2(), 42); + +function fn3(a = function() { var x = 0; }) { + a(); + + return x; +} +assert.sameValue(fn3(), 42); + +function fn4(a = y) { + var y = 1; +} + +// y is only defined on the inner scope of fn4 +assert.throws(ReferenceError, function() { + fn4(); +}); diff --git a/test/language/default-parameters/syntaxerror-on-duplicates-on-function-declaration.js b/test/language/default-parameters/syntaxerror-on-duplicates-on-function-declaration.js new file mode 100644 index 0000000000..f58099f3a2 --- /dev/null +++ b/test/language/default-parameters/syntaxerror-on-duplicates-on-function-declaration.js @@ -0,0 +1,16 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 14.1.2 +description: > + It is a SyntaxError if a a not simple parameters list contains duplicate names +info: > + FormalParameters : FormalParameterList + + It is a Syntax Error if IsSimpleParameterList of FormalParameterList is false + and BoundNames of FormalParameterList contains any duplicate elements. +flags: [noStrict] +negative: SyntaxError +---*/ + +function fn(a, a = 1) {} diff --git a/test/language/default-parameters/syntaxerror-on-duplicates-on-function-expression.js b/test/language/default-parameters/syntaxerror-on-duplicates-on-function-expression.js new file mode 100644 index 0000000000..64e1b915fe --- /dev/null +++ b/test/language/default-parameters/syntaxerror-on-duplicates-on-function-expression.js @@ -0,0 +1,16 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 14.1.2 +description: > + It is a SyntaxError if a a not simple parameters list contains duplicate names +info: > + FormalParameters : FormalParameterList + + It is a Syntax Error if IsSimpleParameterList of FormalParameterList is false + and BoundNames of FormalParameterList contains any duplicate elements. +flags: [noStrict] +negative: SyntaxError +---*/ + +var fn = function (a, a = 1) {}; diff --git a/test/language/default-parameters/variable-initial-value-as-parameter.js b/test/language/default-parameters/variable-initial-value-as-parameter.js new file mode 100644 index 0000000000..42c59aff39 --- /dev/null +++ b/test/language/default-parameters/variable-initial-value-as-parameter.js @@ -0,0 +1,40 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.2.12 +description: > + Vars whose names are in the parameters list, initially have the same value as + the corresponding initialized parameter. +info: > + 9.2.12 FunctionDeclarationInstantiation(func, argumentsList) + + ... + 27. If hasParameterExpressions is false, then + ... + 28. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have visibility + of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv’s EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + f. For each n in varNames, do + i. If n is not an element of instantiatedVarNames, then + 1. Append n to instantiatedVarNames. + 2. Let status be varEnvRec.CreateMutableBinding(n). + 3. Assert: status is never an abrupt completion. + 4. If n is not an element of parameterNames or if n is an element of + functionNames, let initialValue be undefined. + 5. else, + a. Let initialValue be envRec.GetBindingValue(n, false). + ... +---*/ + +function fn(a = 1) { + var a; + + return a; +} + +assert.sameValue(fn(), 1); diff --git a/test/language/default-parameters/variable-initial-value-undefined.js b/test/language/default-parameters/variable-initial-value-undefined.js new file mode 100644 index 0000000000..85f49d6a7b --- /dev/null +++ b/test/language/default-parameters/variable-initial-value-undefined.js @@ -0,0 +1,38 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.2.12 +description: > + A variable initial value is undefined if its name is not in the + parameters list. +info: > + 9.2.12 FunctionDeclarationInstantiation(func, argumentsList) + + ... + 27. If hasParameterExpressions is false, then + ... + 28. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have visibility + of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv’s EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + f. For each n in varNames, do + i. If n is not an element of instantiatedVarNames, then + 1. Append n to instantiatedVarNames. + 2. Let status be varEnvRec.CreateMutableBinding(n). + 3. Assert: status is never an abrupt completion. + 4. If n is not an element of parameterNames or if n is an element of + functionNames, let initialValue be undefined. + ... +---*/ + +function fn(a = 1) { + var b; + + return b; +} + +assert.sameValue(fn(), undefined);