mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 12:19:15 +00:00
test(minifier): port the rest of tests (#6420)
This commit is contained in:
parent
e59da61755
commit
c5deb3235e
2 changed files with 438 additions and 2 deletions
|
|
@ -28,7 +28,7 @@ impl PeepholeReplaceKnownMethods {
|
|||
}
|
||||
}
|
||||
|
||||
/// <https://github.com/google/closure-compiler/blob/master/test/com/google/javascript/jscomp/PeepholeReplaceKnownMethodsTest.java>
|
||||
/// Port from: <https://github.com/google/closure-compiler/blob/master/test/com/google/javascript/jscomp/PeepholeReplaceKnownMethodsTest.java>
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use oxc_allocator::Allocator;
|
||||
|
|
@ -745,4 +745,165 @@ mod test {
|
|||
fold("x = parseInt('021', 8)", "x = 17");
|
||||
fold("x = parseInt('-021', 8)", "x = -17");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_replace_with_char_at() {
|
||||
// enableTypeCheck();
|
||||
// replaceTypesWithColors();
|
||||
// disableCompareJsDoc();
|
||||
|
||||
fold_string_typed("a.substring(0, 1)", "a.charAt(0)");
|
||||
fold_same_string_typed("a.substring(-4, -3)");
|
||||
fold_same_string_typed("a.substring(i, j + 1)");
|
||||
fold_same_string_typed("a.substring(i, i + 1)");
|
||||
fold_same_string_typed("a.substring(1, 2, 3)");
|
||||
fold_same_string_typed("a.substring()");
|
||||
fold_same_string_typed("a.substring(1)");
|
||||
fold_same_string_typed("a.substring(1, 3, 4)");
|
||||
fold_same_string_typed("a.substring(-1, 3)");
|
||||
fold_same_string_typed("a.substring(2, 1)");
|
||||
fold_same_string_typed("a.substring(3, 1)");
|
||||
|
||||
fold_string_typed("a.slice(4, 5)", "a.charAt(4)");
|
||||
fold_same_string_typed("a.slice(-2, -1)");
|
||||
fold_string_typed("var /** number */ i; a.slice(0, 1)", "var /** number */ i; a.charAt(0)");
|
||||
fold_same_string_typed("a.slice(i, j + 1)");
|
||||
fold_same_string_typed("a.slice(i, i + 1)");
|
||||
fold_same_string_typed("a.slice(1, 2, 3)");
|
||||
fold_same_string_typed("a.slice()");
|
||||
fold_same_string_typed("a.slice(1)");
|
||||
fold_same_string_typed("a.slice(1, 3, 4)");
|
||||
fold_same_string_typed("a.slice(-1, 3)");
|
||||
fold_same_string_typed("a.slice(2, 1)");
|
||||
fold_same_string_typed("a.slice(3, 1)");
|
||||
|
||||
fold_string_typed("a.substr(0, 1)", "a.charAt(0)");
|
||||
fold_string_typed("a.substr(2, 1)", "a.charAt(2)");
|
||||
fold_same_string_typed("a.substr(-2, 1)");
|
||||
fold_same_string_typed("a.substr(bar(), 1)");
|
||||
fold_same_string_typed("''.substr(bar(), 1)");
|
||||
fold_same_string_typed("a.substr(2, 1, 3)");
|
||||
fold_same_string_typed("a.substr(1, 2, 3)");
|
||||
fold_same_string_typed("a.substr()");
|
||||
fold_same_string_typed("a.substr(1)");
|
||||
fold_same_string_typed("a.substr(1, 2)");
|
||||
fold_same_string_typed("a.substr(1, 2, 3)");
|
||||
|
||||
// enableTypeCheck();
|
||||
|
||||
fold_same("function f(/** ? */ a) { a.substring(0, 1); }");
|
||||
fold_same("function f(/** ? */ a) { a.substr(0, 1); }");
|
||||
// fold_same(lines(
|
||||
// "/** @constructor */ function A() {};",
|
||||
// "A.prototype.substring = function(begin, end) {};",
|
||||
// "function f(/** !A */ a) { a.substring(0, 1); }",
|
||||
// ));
|
||||
// fold_same(lines(
|
||||
// "/** @constructor */ function A() {};",
|
||||
// "A.prototype.slice = function(begin, end) {};",
|
||||
// "function f(/** !A */ a) { a.slice(0, 1); }",
|
||||
// ));
|
||||
|
||||
// useTypes = false;
|
||||
fold_same_string_typed("a.substring(0, 1)");
|
||||
fold_same_string_typed("a.substr(0, 1)");
|
||||
fold_same_string_typed("''.substring(i, i + 1)");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_fold_concat_chaining() {
|
||||
// enableTypeCheck();
|
||||
|
||||
fold("[1,2].concat(1).concat(2,['abc']).concat('abc')", "[1,2].concat(1,2,['abc'],'abc')");
|
||||
fold("[].concat(['abc']).concat(1).concat([2,3])", "['abc'].concat(1,[2,3])");
|
||||
|
||||
// cannot fold concat based on type information
|
||||
fold_same("returnArrayType().concat(returnArrayType()).concat(1).concat(2)");
|
||||
fold_same("returnArrayType().concat(returnUnionType()).concat(1).concat(2)");
|
||||
fold(
|
||||
"[1,2,1].concat(1).concat(returnArrayType()).concat(2)",
|
||||
"[1,2,1].concat(1).concat(returnArrayType(),2)",
|
||||
);
|
||||
fold(
|
||||
"[1].concat(1).concat(2).concat(returnArrayType())",
|
||||
"[1].concat(1,2).concat(returnArrayType())",
|
||||
);
|
||||
fold_same("[].concat(1).concat(returnArrayType())");
|
||||
fold_same("obj.concat([1,2]).concat(1)");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_remove_array_literal_from_front_of_concat() {
|
||||
// enableTypeCheck();
|
||||
|
||||
fold("[].concat([1,2,3],1)", "[1,2,3].concat(1)");
|
||||
|
||||
fold_same("[1,2,3].concat(returnArrayType())");
|
||||
// Call method with the same name as Array.prototype.concat
|
||||
fold_same("obj.concat([1,2,3])");
|
||||
|
||||
fold_same("[].concat(1,[1,2,3])");
|
||||
fold_same("[].concat(1)");
|
||||
fold("[].concat([1])", "[1].concat()");
|
||||
|
||||
// Chained folding of empty array lit
|
||||
fold("[].concat([], [1,2,3], [4])", "[1,2,3].concat([4])");
|
||||
fold("[].concat([]).concat([1]).concat([2,3])", "[1].concat([2,3])");
|
||||
|
||||
// Cannot fold based on type information
|
||||
fold_same("[].concat(returnArrayType(),1)");
|
||||
fold_same("[].concat(returnArrayType())");
|
||||
fold_same("[].concat(returnUnionType())");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_array_of_spread() {
|
||||
fold("x = Array.of(...['a', 'b', 'c'])", "x = [...['a', 'b', 'c']]");
|
||||
fold("x = Array.of(...['a', 'b', 'c',])", "x = [...['a', 'b', 'c']]");
|
||||
fold("x = Array.of(...['a'], ...['b', 'c'])", "x = [...['a'], ...['b', 'c']]");
|
||||
fold("x = Array.of('a', ...['b', 'c'])", "x = ['a', ...['b', 'c']]");
|
||||
fold("x = Array.of('a', ...['b', 'c'])", "x = ['a', ...['b', 'c']]");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_array_of_no_spread() {
|
||||
fold("x = Array.of('a', 'b', 'c')", "x = ['a', 'b', 'c']");
|
||||
fold("x = Array.of('a', ['b', 'c'])", "x = ['a', ['b', 'c']]");
|
||||
fold("x = Array.of('a', ['b', 'c'],)", "x = ['a', ['b', 'c']]");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_array_of_no_args() {
|
||||
fold("x = Array.of()", "x = []");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_array_of_no_change() {
|
||||
fold_same("x = Array.of.apply(window, ['a', 'b', 'c'])");
|
||||
fold_same("x = ['a', 'b', 'c']");
|
||||
fold_same("x = [Array.of, 'a', 'b', 'c']");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_fold_array_bug() {
|
||||
fold_same("Array[123]()");
|
||||
}
|
||||
|
||||
fn fold_same_string_typed(js: &str) {
|
||||
fold_string_typed(js, js);
|
||||
}
|
||||
|
||||
fn fold_string_typed(js: &str, expected: &str) {
|
||||
let left = "function f(/** string */ a) {".to_string() + js + "}";
|
||||
let right = "function f(/** string */ a) {".to_string() + expected + "}";
|
||||
test(left.as_str(), right.as_str());
|
||||
}
|
||||
}
|
||||
|
|
@ -512,7 +512,7 @@ impl<'a> PeepholeSubstituteAlternateSyntax {
|
|||
}
|
||||
}
|
||||
|
||||
/// <https://github.com/google/closure-compiler/blob/master/test/com/google/javascript/jscomp/PeepholeSubstituteAlternateSyntaxTest.java>
|
||||
/// Port from <https://github.com/google/closure-compiler/blob/master/test/com/google/javascript/jscomp/PeepholeSubstituteAlternateSyntaxTest.java>
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use oxc_allocator::Allocator;
|
||||
|
|
@ -645,4 +645,279 @@ mod test {
|
|||
"x = [{}, [\"abc\", {}, [[]]]]",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_split_comma_expressions() {
|
||||
// late = false;
|
||||
// Don't try to split in expressions.
|
||||
test_same("while (foo(), !0) boo()");
|
||||
test_same("var a = (foo(), !0);");
|
||||
test_same("a = (foo(), !0);");
|
||||
|
||||
// Don't try to split COMMA under LABELs.
|
||||
test_same("a:a(),b()");
|
||||
test("1, 2, 3, 4", "1; 2; 3; 4");
|
||||
test("x = 1, 2, 3", "x = 1; 2; 3");
|
||||
test_same("x = (1, 2, 3)");
|
||||
test("1, (2, 3), 4", "1; 2; 3; 4");
|
||||
test("(x=2), foo()", "x=2; foo()");
|
||||
test("foo(), boo();", "foo(); boo()");
|
||||
test("(a(), b()), (c(), d());", "a(); b(); c(); d()");
|
||||
test("a(); b(); (c(), d());", "a(); b(); c(); d();");
|
||||
test("foo(), true", "foo();true");
|
||||
test_same("foo();true");
|
||||
test("function x(){foo(), !0}", "function x(){foo(); !0}");
|
||||
test_same("function x(){foo(); !0}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_comma1() {
|
||||
// late = false;
|
||||
test("1, 2", "1; 2");
|
||||
// late = true;
|
||||
// test_same("1, 2");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_comma2() {
|
||||
// late = false;
|
||||
test("1, a()", "1; a()");
|
||||
test("1, a?.()", "1; a?.()");
|
||||
|
||||
// late = true;
|
||||
// test_same("1, a()");
|
||||
// test_same("1, a?.()");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_comma3() {
|
||||
// late = false;
|
||||
test("1, a(), b()", "1; a(); b()");
|
||||
test("1, a?.(), b?.()", "1; a?.(); b?.()");
|
||||
|
||||
// late = true;
|
||||
// test_same("1, a(), b()");
|
||||
// test_same("1, a?.(), b?.()");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_comma4() {
|
||||
// late = false;
|
||||
test("a(), b()", "a();b()");
|
||||
test("a?.(), b?.()", "a?.();b?.()");
|
||||
|
||||
// late = true;
|
||||
// test_same("a(), b()");
|
||||
// test_same("a?.(), b?.()");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_comma5() {
|
||||
// late = false;
|
||||
test("a(), b(), 1", "a(); b(); 1");
|
||||
test("a?.(), b?.(), 1", "a?.(); b?.(); 1");
|
||||
|
||||
// late = true;
|
||||
// test_same("a(), b(), 1");
|
||||
// test_same("a?.(), b?.(), 1");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_string_array_splitting() {
|
||||
test_same("var x=['1','2','3','4']");
|
||||
test_same("var x=['1','2','3','4','5']");
|
||||
test("var x=['1','2','3','4','5','6']", "var x='123456'.split('')");
|
||||
test("var x=['1','2','3','4','5','00']", "var x='1 2 3 4 5 00'.split(' ')");
|
||||
test("var x=['1','2','3','4','5','6','7']", "var x='1234567'.split('')");
|
||||
test("var x=['1','2','3','4','5','6','00']", "var x='1 2 3 4 5 6 00'.split(' ')");
|
||||
test("var x=[' ,',',',',',',',',',',']", "var x=' ,;,;,;,;,;,'.split(';')");
|
||||
test("var x=[',,',' ',',',',',',',',']", "var x=',,; ;,;,;,;,'.split(';')");
|
||||
test("var x=['a,',' ',',',',',',',',']", "var x='a,; ;,;,;,;,'.split(';')");
|
||||
|
||||
// all possible delimiters used, leave it alone
|
||||
test_same("var x=[',', ' ', ';', '{', '}']");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_template_string_to_string() {
|
||||
test("`abcde`", "'abcde'");
|
||||
test("`ab cd ef`", "'ab cd ef'");
|
||||
test_same("`hello ${name}`");
|
||||
test_same("tag `hello ${name}`");
|
||||
test_same("tag `hello`");
|
||||
test("`hello ${'foo'}`", "'hello foo'");
|
||||
test("`${2} bananas`", "'2 bananas'");
|
||||
test("`This is ${true}`", "'This is true'");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_bind_to_call1() {
|
||||
test("(goog.bind(f))()", "f()");
|
||||
test("(goog.bind(f,a))()", "f.call(a)");
|
||||
test("(goog.bind(f,a,b))()", "f.call(a,b)");
|
||||
|
||||
test("(goog.bind(f))(a)", "f(a)");
|
||||
test("(goog.bind(f,a))(b)", "f.call(a,b)");
|
||||
test("(goog.bind(f,a,b))(c)", "f.call(a,b,c)");
|
||||
|
||||
test("(goog.partial(f))()", "f()");
|
||||
test("(goog.partial(f,a))()", "f(a)");
|
||||
test("(goog.partial(f,a,b))()", "f(a,b)");
|
||||
|
||||
test("(goog.partial(f))(a)", "f(a)");
|
||||
test("(goog.partial(f,a))(b)", "f(a,b)");
|
||||
test("(goog.partial(f,a,b))(c)", "f(a,b,c)");
|
||||
|
||||
test("((function(){}).bind())()", "((function(){}))()");
|
||||
test("((function(){}).bind(a))()", "((function(){})).call(a)");
|
||||
test("((function(){}).bind(a,b))()", "((function(){})).call(a,b)");
|
||||
|
||||
test("((function(){}).bind())(a)", "((function(){}))(a)");
|
||||
test("((function(){}).bind(a))(b)", "((function(){})).call(a,b)");
|
||||
test("((function(){}).bind(a,b))(c)", "((function(){})).call(a,b,c)");
|
||||
|
||||
// Without using type information we don't know "f" is a function.
|
||||
test_same("(f.bind())()");
|
||||
test_same("(f.bind(a))()");
|
||||
test_same("(f.bind())(a)");
|
||||
test_same("(f.bind(a))(b)");
|
||||
|
||||
// Don't rewrite if the bind isn't the immediate call target
|
||||
test_same("(goog.bind(f)).call(g)");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_bind_to_call2() {
|
||||
test("(goog$bind(f))()", "f()");
|
||||
test("(goog$bind(f,a))()", "f.call(a)");
|
||||
test("(goog$bind(f,a,b))()", "f.call(a,b)");
|
||||
|
||||
test("(goog$bind(f))(a)", "f(a)");
|
||||
test("(goog$bind(f,a))(b)", "f.call(a,b)");
|
||||
test("(goog$bind(f,a,b))(c)", "f.call(a,b,c)");
|
||||
|
||||
test("(goog$partial(f))()", "f()");
|
||||
test("(goog$partial(f,a))()", "f(a)");
|
||||
test("(goog$partial(f,a,b))()", "f(a,b)");
|
||||
|
||||
test("(goog$partial(f))(a)", "f(a)");
|
||||
test("(goog$partial(f,a))(b)", "f(a,b)");
|
||||
test("(goog$partial(f,a,b))(c)", "f(a,b,c)");
|
||||
// Don't rewrite if the bind isn't the immediate call target
|
||||
test_same("(goog$bind(f)).call(g)");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_bind_to_call3() {
|
||||
// TODO(johnlenz): The code generator wraps free calls with (0,...) to
|
||||
// prevent leaking "this", but the parser doesn't unfold it, making a
|
||||
// AST comparison fail. For now do a string comparison to validate the
|
||||
// correct code is in fact generated.
|
||||
// The FREE call wrapping should be moved out of the code generator
|
||||
// and into a denormalizing pass.
|
||||
// disableCompareAsTree();
|
||||
// retraverseOnChange = true;
|
||||
// late = false;
|
||||
|
||||
test("(goog.bind(f.m))()", "(0,f.m)()");
|
||||
test("(goog.bind(f.m,a))()", "f.m.call(a)");
|
||||
|
||||
test("(goog.bind(f.m))(a)", "(0,f.m)(a)");
|
||||
test("(goog.bind(f.m,a))(b)", "f.m.call(a,b)");
|
||||
|
||||
test("(goog.partial(f.m))()", "(0,f.m)()");
|
||||
test("(goog.partial(f.m,a))()", "(0,f.m)(a)");
|
||||
|
||||
test("(goog.partial(f.m))(a)", "(0,f.m)(a)");
|
||||
test("(goog.partial(f.m,a))(b)", "(0,f.m)(a,b)");
|
||||
|
||||
// Without using type information we don't know "f" is a function.
|
||||
test_same("f.m.bind()()");
|
||||
test_same("f.m.bind(a)()");
|
||||
test_same("f.m.bind()(a)");
|
||||
test_same("f.m.bind(a)(b)");
|
||||
|
||||
// Don't rewrite if the bind isn't the immediate call target
|
||||
test_same("goog.bind(f.m).call(g)");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_simple_function_call1() {
|
||||
test("var a = String(23)", "var a = '' + 23");
|
||||
// Don't fold the existence check to preserve behavior
|
||||
test_same("var a = String?.(23)");
|
||||
|
||||
test("var a = String('hello')", "var a = '' + 'hello'");
|
||||
// Don't fold the existence check to preserve behavior
|
||||
test_same("var a = String?.('hello')");
|
||||
|
||||
test_same("var a = String('hello', bar());");
|
||||
test_same("var a = String({valueOf: function() { return 1; }});");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_simple_function_call2() {
|
||||
test("var a = Boolean(true)", "var a = !0");
|
||||
// Don't fold the existence check to preserve behavior
|
||||
test("var a = Boolean?.(true)", "var a = Boolean?.(!0)");
|
||||
|
||||
test("var a = Boolean(false)", "var a = !1");
|
||||
// Don't fold the existence check to preserve behavior
|
||||
test("var a = Boolean?.(false)", "var a = Boolean?.(!1)");
|
||||
|
||||
test("var a = Boolean(1)", "var a = !!1");
|
||||
// Don't fold the existence check to preserve behavior
|
||||
test_same("var a = Boolean?.(1)");
|
||||
|
||||
test("var a = Boolean(x)", "var a = !!x");
|
||||
// Don't fold the existence check to preserve behavior
|
||||
test_same("var a = Boolean?.(x)");
|
||||
|
||||
test("var a = Boolean({})", "var a = !!{}");
|
||||
// Don't fold the existence check to preserve behavior
|
||||
test_same("var a = Boolean?.({})");
|
||||
|
||||
test_same("var a = Boolean()");
|
||||
test_same("var a = Boolean(!0, !1);");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_rotate_associative_operators() {
|
||||
test("a || (b || c); a * (b * c); a | (b | c)", "(a || b) || c; (a * b) * c; (a | b) | c");
|
||||
test_same("a % (b % c); a / (b / c); a - (b - c);");
|
||||
test("a * (b % c);", "b % c * a");
|
||||
test("a * b * (c / d)", "c / d * b * a");
|
||||
test("(a + b) * (c % d)", "c % d * (a + b)");
|
||||
test_same("(a / b) * (c % d)");
|
||||
test_same("(c = 5) * (c % d)");
|
||||
test("(a + b) * c * (d % e)", "d % e * c * (a + b)");
|
||||
test("!a * c * (d % e)", "d % e * c * !a");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn nullish_coalesce() {
|
||||
test("a ?? (b ?? c);", "(a ?? b) ?? c");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_no_rotate_infinite_loop() {
|
||||
test("1/x * (y/1 * (1/z))", "1/x * (y/1) * (1/z)");
|
||||
test_same("1/x * (y/1) * (1/z)");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue