swc/crates/swc_ecma_transforms_compat/tests/es2015_parameters.rs
Donny/강동윤 0aafa75fef
feat(es/testing): Use __swc_snapshots__ for test! macro (#8191)
**Description:**

This implements something similar to `__snapshots__` of `jest`. Instead of storing the expected result as a string literal, we now store it in `$crate/tests/__swc_snapshots__/$path_to_test__$test_name.js`.

**Related issue:**

 - Closes #4509
2023-10-30 10:38:59 +09:00

1489 lines
29 KiB
Rust

use std::path::PathBuf;
use swc_common::{chain, comments::SingleThreadedComments, Mark};
use swc_ecma_parser::Syntax;
use swc_ecma_transforms_base::resolver;
use swc_ecma_transforms_compat::{
es2015::{
arrow, block_scoping, classes, destructuring, parameters, parameters::Config, spread,
},
es2017::async_to_generator,
};
use swc_ecma_transforms_testing::{test, test_exec, test_fixture};
use swc_ecma_visit::Fold;
fn syntax() -> Syntax {
Default::default()
}
fn tr(c: Config) -> impl Fold {
let unresolved_mark = Mark::new();
let top_level_mark = Mark::new();
chain!(
resolver(unresolved_mark, top_level_mark, false),
parameters(c, unresolved_mark),
destructuring(destructuring::Config { loose: false }),
block_scoping(unresolved_mark),
)
}
test!(
syntax(),
|_| tr(Default::default()),
issue_254,
"export const someFunction = (update = false, action = {}) => {}"
);
test!(
syntax(),
|_| tr(Default::default()),
issue_227,
"export default function fn1(...args) {
fn2(...args);
}"
);
test!(
syntax(),
|_| tr(Default::default()),
issue_169,
r#"
class Foo {
func(a, b = Date.now()) {
return {a};
}
}
"#
);
test!(
syntax(),
|_| tr(Default::default()),
babel_6057_simple,
r#"const a = 'bar';
function foo(...a) {
return a;
}"#
);
test!(
syntax(),
|_| tr(Default::default()),
default_before_last,
r#"function foo({x,y} = "foo", b) {}"#
);
test_exec!(
syntax(),
|_| tr(Default::default()),
default_destructuring,
r#"function required(msg) {
throw new Error(msg);
}
function sum(
{ arr = required('arr is required') } = { arr: arr = [] },
length = arr.length
) {
let i = 0;
let acc = 0;
for (let item of arr) {
if (i >= length) return acc;
acc += item;
i++;
}
return acc;
}
expect(sum({arr:[1,2]})).toBe(3);"#
);
test_exec!(
syntax(),
|_| tr(Default::default()),
default_earlier_params,
r#"function f(a, b = a, c = b) { return c; }
expect(3).toBe(f(3));"#
);
test!(
ignore,
syntax(),
|_| tr(Default::default()),
default_eval,
r#"let x = "outside";
function outer(a = () => eval("x")) {
let x = "inside";
return a();
}
outer();"#
);
test_exec!(
syntax(),
|_| tr(Default::default()),
default_iife_1128,
r#"const bar = true;
function foo(a = bar, ...b) {
const bar = false;
expect(b[0]).toBe(2);
expect(b[1]).toBe(3);
}
foo(1, 2, 3);"#
);
test!(
syntax(),
|t| chain!(
classes(Some(t.comments.clone()), Default::default()),
tr(Default::default())
),
default_iife_4253,
r#"class Ref {
constructor(id = ++Ref.nextID) {
this.id = id
}
}
Ref.nextID = 0"#
);
test_exec!(
ignore,
syntax(),
// Stage0
|_| tr(Default::default()),
default_iife_4253_exec,
r#"class Ref {
static nextId = 0
constructor(id = ++Ref.nextId, n = id) {
this.id = n
}
}
expect(new Ref().id).toBe(1);
expect(new Ref().id).toBe(2);"#
);
test!(
syntax(),
|t| chain!(
classes(Some(t.comments.clone()), Default::default()),
tr(Default::default())
),
default_iife_self,
r#"class Ref {
constructor(ref = Ref) {
this.ref = ref
}
}
class X {
constructor(x = foo) {
this.x = x
}
}"#
);
test_exec!(
syntax(),
|_| tr(Default::default()),
default_iife_self_exec,
r#"class Ref {
constructor(ref = Ref) {
this.ref = ref
}
}
expect(new Ref().ref).toBe(Ref);"#
);
test!(
syntax(),
|_| tr(Default::default()),
default_multiple,
r#"var t = function (e = "foo", f = 5) {
return e + " bar " + f;
};
var a = function (e, f = 5) {
return e + " bar " + f;
};"#
);
test!(
syntax(),
|_| tr(Default::default()),
default_rest_mix,
r#"function fn(
a1,
a2 = 4,
{a3, a4},
a5,
{a6, a7} = {}) {}"#
);
test!(
syntax(),
|_| tr(Default::default()),
default_rest_1,
r#"const a = 1;
function rest(b = a, ...a) {
expect(b).toBe(1);
}
rest(undefined, 2)"#
);
test!(
syntax(),
|_| tr(Default::default()),
default_rest_2,
r#"const a = 1;
function rest2(b = a, ...a) {
expect(a[0]).toBe(2);
}
rest2(undefined, 2);"#
);
test!(
syntax(),
|_| tr(Default::default()),
default_rest_3,
r#"const a = 1;
function rest3(b = a, ...a) {
expect(a).toHaveLength(1);
}
rest3(undefined, 2)"#
);
test_exec!(
syntax(),
|_| tr(Default::default()),
default_rest_exec,
r#"const a = 1;
function rest(b = a, ...a) {
expect(b).toBe(1);
}
rest(undefined, 2)
function rest2(b = a, ...a) {
expect(a[0]).toBe(2);
}
rest2(undefined, 2)
function rest3(b = a, ...a) {
expect(a).toHaveLength(1);
}
rest3(undefined, 2)"#
);
test!(
syntax(),
|_| tr(Default::default()),
default_setter_noexec,
r#"const obj = {
set field(num = 1) {
this.num = num;
}
};"#
);
test!(
syntax(),
|_| tr(Default::default()),
default_setter_complex,
r#"const obj = {
set obj({ a, b } = {}) {
this.num = { a, b };
},
set arr([x, y] = []) {
this.num = { x, y }
}
};"#
);
test_exec!(
syntax(),
|_| tr(Default::default()),
default_setter_exec,
r#"const defaultValue = 1;
const obj = {
set field(num = defaultValue) {
this.num = num;
}
};
obj.field = void 0;
expect(obj.num).toBe(defaultValue);"#
);
test!(
syntax(),
|_| tr(Default::default()),
default_single,
r#"var t = function (f = "foo") {
return f + " bar";
};"#
);
test!(
syntax(),
|_| tr(Default::default()),
destructuring_rest,
r#"// #3861
function t(x = "default", { a, b }, ...args) {
console.log(x, a, b, args);
}"#
);
test!(
syntax(),
|_| tr(Default::default()),
regression_4333,
r#"const args = 'bar';
function foo(...args) {
return args;
}"#
);
test!(
syntax(),
|_| tr(Default::default()),
regression_4348,
r#"function first(...values) {
var index = 0;
return values[index++];
}"#
);
test!(
ignore,
syntax(),
// type
|_| tr(Default::default()),
regression_4634,
r#"let oneOf = (...nodes) => {
if (nodes.length === 1) {
return nodes[0];
}
return ((new OneOfNode(nodes)): any)
}"#
);
test!(
syntax(),
|_| tr(Default::default()),
regression_5787,
r#"function f(a, ...rest) {
let b = rest[rest.length - 3];
let c = rest[rest.length - 2];
let d = rest[rest.length - 1];
return [a, b, c, d];
}
function f(a, ...rest) {
return rest[-1];
}"#
);
test_exec!(
syntax(),
|_| tr(Default::default()),
regression_5787_exec,
r#"function f1(a, ...rest) {
let b = rest[rest.length - 3];
let c = rest[rest.length - 2];
let d = rest[rest.length - 1];
return [a, b, c, d];
}
expect(f1(1, 2)).toEqual([1, undefined, undefined, 2]);
function f2(a, ...rest) {
return rest[-1];
}
expect(f2(1, 2)).toBeUndefined();"#
);
test!(
syntax(),
|_| tr(Default::default()),
rest_args_deoptimiazation,
r#"function x (...rest) {
arguments;
}"#
);
test!(
// Stage 0
ignore,
syntax(),
|_| tr(Default::default()),
rest_arrow_fn,
r#"var concat = (...arrs) => {
var x = arrs[0];
var y = arrs[1];
};
var somefun = function () {
let get2ndArg = (a, b, ...args) => {
var _b = args[0];
let somef = (x, y, z, ...args2) => {
var _a = args2[0];
};
let somefg = (c, d, e, f, ...args3) => {
var _a = args3[0];
};
var _d = args[1];
};
let get3rdArg = (...args) => args[2];
}
function demo1(...args) {
return (i) => {
return args[i+0];
};
}
var x = (...rest) => {
if (noNeedToWork) return 0;
return rest;
};
var innerclassproperties = (...args) => (
class {
static args = args;
args = args;
}
);"#
);
test!(
ignore,
syntax(),
|_| tr(Default::default()),
rest_async_arrow_fn,
r#"var concat = async (...arrs) => {
var x = arrs[0];
var y = arrs[1];
};
var x = async (...rest) => {
if (noNeedToWork) return 0;
return rest;
};"#
);
test!(
syntax(),
|_| {
let unresolved_mark = Mark::new();
let top_level_mark = Mark::new();
chain!(
arrow(unresolved_mark),
resolver(unresolved_mark, top_level_mark, false),
parameters(Default::default(), unresolved_mark),
destructuring(destructuring::Config { loose: false }),
block_scoping(unresolved_mark),
)
},
rest_binding_deoptimisation,
r#"const deepAssign = (...args) => args = [];
"#
);
test!(
// optimization is not implemented
ignore,
syntax(),
|_| tr(Default::default()),
rest_deepest_common_ancestor_earliest_child,
r#"// single reference
function r(...rest){
if (noNeedToWork) return 0;
return rest;
}
// multiple references
function r(...rest){
if (noNeedToWork) return 0;
rest;
rest;
}
// multiple nested references
function r(...rest){
if (noNeedToWork) return 0;
if (true) {
return rest;
} else {
return rest;
}
}
// deeply nested
function r(...rest){
if (true) {
if (true) {
return rest;
} else {
return rest;
}
}
}
// nested reference with root reference
function r(...rest){
if (noNeedToWork) return 0;
if (lol) rest;
rest;
}
// nested functions
function a(...args) {
return function() {
function b() {}
console.log("Shouldn't args be from a's scope?" args);
};
}
// loop
function runQueue(queue, ...args) {
for (let i = 0; i < queue.length; i++) {
queue[i](...args)
}
}
// nested loop
function runQueue(queue, ...args) {
if (foo) {
for (let i = 0; i < queue.length; i++) {
queue[i](...args)
}
}
}
function r(...rest){
if (noNeedToWork) return 0;
[rest[0]] = x;
return rest;
}"#
);
test!(
syntax(),
|_| tr(Default::default()),
rest_length,
r#"var t = function (f, ...items) {
items[0];
items[items.length - 1];
};
function t(f, ...items) {
items;
items[0];
items[items.length - 1];
}"#
);
test_exec!(
syntax(),
|_| tr(Default::default()),
rest_length_exec,
r#"var length = function (a, b, ...items) {
return items.length;
};
expect(length()).toBe(0);
expect(length(1)).toBe(0);
expect(length(1, 2)).toBe(0);
expect(length(1, 2, 3)).toBe(1);"#
);
test!(
// optimisation is not implemented
ignore,
syntax(),
|_| tr(Default::default()),
rest_member_expression_deoptimisation,
r#"var t = function (...items) {
var x = items[0];
var y = items[1];
}
function t(...items) {
var x = items[0];
var y = items[1];
}
function t(...items) {
var a = [];
for (var i = 0; i < items.length; i++) {
a.push(i);
}
return a;
}
// https://github.com/babel/babel/pull/2833#issuecomment-166039291
function t(...items) {
for (let i = 0; i < items.length; i++) {
return items[i];
}
}"#
);
test!(
// optimisation is not implemented
ignore,
syntax(),
|_| tr(Default::default()),
rest_member_expression_optimisation,
r#"var t = function (...items) {
var x = items[0];
var y = items[1];
}
function t(...items) {
var x = items[0];
var y = items[1];
}
function t(...items) {
var a = [];
for (var i = 0; i < items.length; i++) {
a.push(i);
}
return a;
}
// https://github.com/babel/babel/pull/2833#issuecomment-166039291
function t(...items) {
for (let i = 0; i < items.length; i++) {
return items[i];
}
}"#
);
test!(
syntax(),
|_| tr(Default::default()),
rest_multiple,
r#"var t = function (f, ...items) {
var x = f;
x = items[0];
x = items[1];
};
function t(f, ...items) {
var x = f;
x = items[0];
x = items[1];
}
function u(f, g, ...items) {
var x = f;
var y = g;
x[12] = items[0];
y.prop = items[1];
var z = items[2] | 0 || 12;
}"#
);
test!(
// optimisation is not implemented
ignore,
syntax(),
|_| tr(Default::default()),
rest_nested_5656,
r#"function a(...args) {
const foo = (...list) => bar(...list);
foo(...args);
}
function b(...args) {
const foo = (...args) => bar(...args);
foo(...args);
}
function c(...args) {
const foo = (...args) => bar(...args);
foo([]);
}
function d(thing, ...args) {
const foo = (...args) => bar(...args);
{
let args = thing;
foo(thing);
}
}"#
);
test!(
syntax(),
|t| chain!(
tr(Default::default()),
classes(Some(t.comments.clone()), Default::default()),
spread(Default::default())
),
rest_nested_iife,
r#"function broken(x, ...foo) {
if (true) {
class Foo extends Bar { }
return hello(...foo)
}
}"#
);
test!(
syntax(),
|_| tr(Default::default()),
rest_patterns,
r#"function foo(...[a]) {}"#
);
test_exec!(
syntax(),
|_| tr(Default::default()),
rest_patterns_exec,
r#"
function foo(...{ length }) {
return length;
}
expect(foo(1, 2, 3)).toEqual(3);"#
);
test!(
// optimisation is not implemented
ignore,
syntax(),
|_| tr(Default::default()),
rest_spread_optimisation,
r#"// optimisation
function foo(...bar) {
foo(...bar);
}
// deoptimisation
function foo(a, ...b) {
foo(...b);
}
function foo(...b) {
foo(1, ...b);
}
function foo(...args){
args.pop()
foo(...args);
}"#
);
//// regression_6057_expanded
//test!(
// syntax(),
// |_| tr(r#"{
// "presets": ["env"],
// "plugins": ["proposal-class-properties"]
//}
//"#),
// regression_6057_expanded,
// r#"
//import args from 'utils/url/args';
//
//export default class App extends Component {
// exportType = ''
//
// componentDidMount() {
// this.exportType = args.get('type', window.location.href);
// }
//}
//
//"#
// r#"
//"use strict";
//
//Object.defineProperty(exports, "__esModule" {
// value: true
//});
//exports["default"] = void 0;
//
//var _args = _interop_require_default(require("utils/url/args"));
//
//function _interop_require_default(obj) { return obj && obj.__esModule ? obj :
// { "default": obj }; }
//
//function _typeof(obj) { if (typeof Symbol === "function" && typeof
// Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return
// typeof obj; }; } else { _typeof = function _typeof(obj) { return obj &&
// typeof Symbol === "function" && obj.constructor === Symbol && obj !==
// Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
//
//function _class_call_check(instance, Constructor) { if (!(instance instanceof
// Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
//
//function _defineProperties(target, props) { for (var i = 0; i < props.length;
// i++) { var descriptor = props[i]; descriptor.enumerable =
// descriptor.enumerable || false; descriptor.configurable = true; if ("value"
// in descriptor) descriptor.writable = true; Object.defineProperty(target,
// descriptor.key, descriptor); } }
//
//function _create_class(Constructor, protoProps, staticProps) { if
// (protoProps) _defineProperties(Constructor.prototype, protoProps); if
// (staticProps) _defineProperties(Constructor, staticProps); return
// Constructor; }
//
//function _possible_constructor_return(self, call) { if (call &&
// (_typeof(call) === "object" || typeof call === "function")) { return call; }
// return _assert_this_initialized(self); }
//
//function _get_prototype_of(o) { _get_prototype_of = Object.setPrototypeOf ?
// Object.getPrototypeOf : function _get_prototype_of(o) { return o.__proto__ ||
// Object.getPrototypeOf(o); }; return _get_prototype_of(o); }
//
//function _assert_this_initialized(self) { if (self === void 0) { throw new
// ReferenceError("this hasn't been initialised - super() hasn't been called");
// } return self; }
//
//function _inherits(subClass, superClass) { if (typeof superClass !==
// "function" && superClass !== null) { throw new TypeError("Super expression
// must either be null or a function"); } subClass.prototype =
// Object.create(superClass && superClass.prototype, { constructor: { value:
// subClass, writable: true, configurable: true } }); if (superClass)
// _set_prototype_of(subClass, superClass); }
//
//function _set_prototype_of(o, p) { _set_prototype_of = Object.setPrototypeOf
// || function _set_prototype_of(o, p) { o.__proto__ = p; return o; }; return
// _set_prototype_of(o, p); }
//
//function _define_property(obj, key, value) { if (key in obj) {
// Object.defineProperty(obj, key, { value: value, enumerable: true,
// configurable: true, writable: true }); } else { obj[key] = value; } return
// obj; }
//
//var App =
// /*#__PURE__*/
//function (_Component) {
// _inherits(App, _Component);
//
// function App() {
// var _get_prototype_of2;
//
// var _this;
//
// _class_call_check(this, App);
//
// for (var _len = arguments.length, args = new Array(_len), _key = 0; _key <
// _len; _key++) { args[_key] = arguments[_key];
// }
//
// _this = _possible_constructor_return(this, (_get_prototype_of2 =
// _get_prototype_of(App)).call.apply(_get_prototype_of2, [this].concat(args)));
//
// _define_property(_assert_this_initialized(_this), "exportType" '');
//
// return _this;
// }
//
// _create_class(App, [{
// key: "componentDidMount"
// value: function componentDidMount() {
// this.exportType = _args["default"].get('type', window.location.href);
// }
// }]);
//
// return App;
//}(Component);
//
//exports["default"] = App;
//
//"#
//);
//// parameters_iife_this_9385
//test!(
// syntax(),
// |_| tr(r#"{
// "plugins": ["transform-typescript"],
// "presets": ["env"]
//}
//"#),
// parameters_iife_this_9385,
// r#"
//export class Test {
// invite(options: { privacy: string } = {}) {
// const privacy = options.privacy || "Private"
// console.log(this)
// }
//}
//"#
// r#"
//"use strict";
//
//Object.defineProperty(exports, "__esModule" {
// value: true
//});
//exports.Test = void 0;
//
//function _class_call_check(instance, Constructor) { if (!(instance instanceof
// Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
//
//function _defineProperties(target, props) { for (var i = 0; i < props.length;
// i++) { var descriptor = props[i]; descriptor.enumerable =
// descriptor.enumerable || false; descriptor.configurable = true; if ("value"
// in descriptor) descriptor.writable = true; Object.defineProperty(target,
// descriptor.key, descriptor); } }
//
//function _create_class(Constructor, protoProps, staticProps) { if
// (protoProps) _defineProperties(Constructor.prototype, protoProps); if
// (staticProps) _defineProperties(Constructor, staticProps); return
// Constructor; }
//
//var Test =
// /*#__PURE__*/
//function () {
// function Test() {
// _class_call_check(this, Test);
// }
//
// _create_class(Test, [{
// key: "invite"
// value: function invite() {
// var options = arguments.length > 0 && arguments[0] !== undefined ?
// arguments[0] : {}; var privacy = options.privacy || "Private";
// console.log(this);
// }
// }]);
//
// return Test;
//}();
//
//exports.Test = Test;
//
//"#
//);
// parameters_rest_async_arrow_functions
test!(
// See https://github.com/swc-project/swc/issues/490
ignore,
syntax(),
|_| {
let unresolved_mark = Mark::new();
let top_level_mark = Mark::new();
chain!(
resolver(unresolved_mark, top_level_mark, false),
async_to_generator::<SingleThreadedComments>(Default::default(), None, unresolved_mark),
arrow(unresolved_mark),
parameters(Default::default(), unresolved_mark),
)
},
parameters_rest_async_arrow_functions_1,
r#"
var concat = async (...arrs) => {
var x = arrs[0];
var y = arrs[1];
};
"#
);
// parameters_rest_async_arrow_functions
test!(
// See https://github.com/swc-project/swc/issues/490
ignore,
syntax(),
|_| {
let unresolved_mark = Mark::new();
let top_level_mark = Mark::new();
chain!(
resolver(unresolved_mark, top_level_mark, false),
async_to_generator::<SingleThreadedComments>(Default::default(), None, unresolved_mark),
arrow(unresolved_mark),
parameters(Default::default(), unresolved_mark),
)
},
parameters_rest_async_arrow_functions_2,
r#"
var x = async (...rest) => {
if (noNeedToWork) return 0;
return rest;
};
"#
);
// regression_6057_simple
test!(
syntax(),
|_| {
let unresolved_mark = Mark::new();
let top_level_mark = Mark::new();
chain!(
resolver(unresolved_mark, top_level_mark, false),
parameters(Default::default(), unresolved_mark),
)
},
regression_6057_simple,
r#"
const a = 'bar';
function foo(...a) {
return a;
}
"#
);
// parameters_regression_4333
test!(
syntax(),
|_| {
let unresolved_mark = Mark::new();
let top_level_mark = Mark::new();
chain!(
resolver(unresolved_mark, top_level_mark, false),
parameters(Default::default(), unresolved_mark),
block_scoping(unresolved_mark)
)
},
parameters_regression_4333,
r#"
const args = 'bar';
function foo(...args) {
return args;
}
"#
);
test!(
syntax(),
|_| {
let unresolved_mark = Mark::new();
let top_level_mark = Mark::new();
chain!(
resolver(unresolved_mark, top_level_mark, false),
parameters(Default::default(), unresolved_mark),
destructuring(Default::default())
)
},
issue_760,
"const initialState = 'foo'
export default function reducer(state = initialState, action = {}) {
}"
);
test!(
syntax(),
|_| {
let unresolved_mark = Mark::new();
let top_level_mark = Mark::new();
chain!(
resolver(unresolved_mark, top_level_mark, false),
parameters(Default::default(), unresolved_mark),
)
},
rest_in_top_level_arrow_1,
"
const arrow = (...args) => {
console.log(args);
}
"
);
test!(
syntax(),
|_| {
let unresolved_mark = Mark::new();
let top_level_mark = Mark::new();
chain!(
resolver(unresolved_mark, top_level_mark, false),
parameters(Default::default(), unresolved_mark),
)
},
rest_in_top_level_arrow_2,
"
const arrow = () => (...args) => {
console.log(args);
}
"
);
test!(
syntax(),
|_| {
let unresolved_mark = Mark::new();
let top_level_mark = Mark::new();
chain!(
resolver(unresolved_mark, top_level_mark, false),
parameters(Default::default(), unresolved_mark),
)
},
rest_in_top_level_arrow_3,
"
const arrow = () => (...args) => {
console.log(this, args);
}
"
);
test!(
syntax(),
|_| {
let unresolved_mark = Mark::new();
let top_level_mark = Mark::new();
chain!(
resolver(unresolved_mark, top_level_mark, false),
parameters(Default::default(), unresolved_mark),
)
},
rest_in_top_level_arrow_4,
"
const arrow = () => (this, (...args) => {
console.log(this, args);
})
"
);
test!(
syntax(),
|_| {
let unresolved_mark = Mark::new();
let top_level_mark = Mark::new();
chain!(
resolver(unresolved_mark, top_level_mark, false),
parameters(Default::default(), unresolved_mark),
)
},
rest_in_top_level_arrow_nested_1,
"
const arrow = (...args) => (this, () => (...args) => {
console.log(this, args);
})
"
);
test!(
syntax(),
|_| tr(Default::default()),
issue_2825,
"
const foo = (...rest) => console.log(this, rest)
const bar = () => this
"
);
test!(
syntax(),
|_| tr(Default::default()),
issue_2811,
"
class Foo extends (function(){}) {
constructor(){
var foo = (...rest) => [rest, this];
if (true){
console.log(super(), foo());
} else {
super();
console.log(foo());
}
}
}
"
);
test!(
syntax(),
|_| {
let unresolved_mark = Mark::new();
let top_level_mark = Mark::new();
chain!(
resolver(unresolved_mark, top_level_mark, false),
parameters(Default::default(), unresolved_mark),
)
},
issue_3471,
"
class A {
a = 1 + ((...a) => a)
b = (...b) => b + this
static c = (c = 123) => c + this
}
"
);
test!(
syntax(),
|_| {
let unresolved_mark = Mark::new();
let top_level_mark = Mark::new();
chain!(
resolver(unresolved_mark, top_level_mark, false),
parameters(Default::default(), unresolved_mark),
)
},
issue_3569,
"
export class TableView extends React.Component {
constructor(props){
super(props);
this.getSearchForm = (innerWidth = 0)=>{
this.getProps();
};
}
}
"
);
test!(
syntax(),
|_| tr(Config {
ignore_function_length: true
}),
fn_len_complex_assign,
"function test({a: b} = {}) {}"
);
test!(
syntax(),
|_| tr(Config {
ignore_function_length: true
}),
fn_len_default_array_destructuring,
"function t([,,a] = [1,2,3]) { return a }"
);
test_exec!(
syntax(),
|_| tr(Config {
ignore_function_length: true
}),
fn_len_default_array_destructuring_exec,
"function t([,,a] = [1,2,3]) { return a }
expect(t()).toBe(3);
expect(t([4,5,6])).toBe(6);"
);
test_exec!(
syntax(),
|_| tr(Config {
ignore_function_length: true
}),
fn_len_default_earlier_params,
"function f(a, b = a, c = b) { return c; }
expect(f(3)).toBe(3);"
);
test_exec!(
syntax(),
|_| tr(Config {
ignore_function_length: true
}),
fn_len_default_iife_1128,
"const bar = true;
function foo(a = bar, ...b) {
const bar = false;
expect(b[0]).toBe(2);
expect(b[1]).toBe(3);
}
foo(1, 2, 3);"
);
test_exec!(
syntax(),
|_| tr(Config {
ignore_function_length: true
}),
fn_len_default_iife_4253,
"class Ref {
static nextId = 0
constructor(id = ++Ref.nextId, n = id) {
this.id = n
}
}
expect(new Ref().id).toBe(1);
expect(new Ref().id).toBe(2);"
);
test_exec!(
syntax(),
|_| tr(Config {
ignore_function_length: true
}),
fn_len_default_iife_self,
"class Ref {
constructor(ref = Ref) {
this.ref = ref
}
}
expect(new Ref().ref).toBe(Ref);"
);
test!(
syntax(),
|_| tr(Config {
ignore_function_length: true
}),
fn_len_default_multiple,
r#"
var t = function (e = "foo", f = 5) {
return e + " bar " + f;
};
var a = function (e, f = 5) {
return e + " bar " + f;
};"#
);
test_exec!(
syntax(),
|_| tr(Config {
ignore_function_length: true
}),
fn_len_object_destructuring,
"function required(msg) {
throw new Error(msg);
}
function sum(
{ arr = required('arr is required') } = { arr: arr = [] },
length = arr.length
) {
let i = 0;
let acc = 0;
for (let item of arr) {
if (i >= length) return acc;
acc += item;
i++;
}
return acc;
}
expect(sum({arr:[1,2]})).toBe(3);"
);
test!(
syntax(),
|_| tr(Config {
ignore_function_length: true
}),
fn_len_rest_mix,
r#"
function fn(
a1,
a2 = 4,
{a3, a4},
a5,
{a6, a7} = {}) {
}"#
);
test_exec!(
syntax(),
|_| tr(Config {
ignore_function_length: true
}),
fn_len_rest,
"const a = 1;
function rest(b = a, ...a) {
expect(b).toBe(1);
}
rest(undefined, 2)
function rest2(b = a, ...a) {
expect(a[0]).toBe(2);
}
rest2(undefined, 2)
function rest3(b = a, ...a) {
expect(a).toHaveLength(1);
}
rest3(undefined, 2)"
);
test!(
syntax(),
|_| tr(Config {
ignore_function_length: true
}),
fn_len_default_single,
r#"
var t = function (f = "foo") {
return f + " bar";
};"#
);
test!(
syntax(),
|_| tr(Config {
ignore_function_length: true
}),
fn_len_destructing_rest,
r#"
function t(x = "default", { a, b }, ...args) {
console.log(x, a, b, args);
}"#
);
test_exec!(
syntax(),
|_| tr(Config {
ignore_function_length: true
}),
fn_len_overwrite_undefined,
"function t(undefined = 17, a = 3) {
return a;
}
expect(t()).toBe(3);"
);
test!(
syntax(),
|_| tr(Config {
ignore_function_length: true
}),
issue_5030,
r#"
let v0 = (Array, Int8Array, ...Int32Array) => (NaN + Infinity) * Int32Array.length;
console.log(v0(1, 2, 'hello', true, 7));
"#
);
#[testing::fixture("tests/parameters/**/input.js")]
fn fixture(input: PathBuf) {
let output = input.with_file_name("output.js");
test_fixture(
Default::default(),
&|_| {
let unresolved_mark = Mark::new();
chain!(
resolver(unresolved_mark, Mark::new(), false),
parameters(Default::default(), unresolved_mark)
)
},
&input,
&output,
Default::default(),
);
}