use of com.google.javascript.jscomp.testing.TestExternsBuilder in project closure-compiler by google.
the class TypedScopeCreatorTest method testGoogProvide_overwritingExternsFunction.
@Test
public void testGoogProvide_overwritingExternsFunction() {
processClosurePrimitives = true;
testSame(externs(new TestExternsBuilder().addClosureExterns().addExtra("/** @externs */ function eval(code) {}").build()), srcs(lines(//
"goog.provide('eval.subNs');", "eval.subNs = class {};", "new eval.subNs();")), warning(TypeValidator.DUP_VAR_DECLARATION_TYPE_MISMATCH));
}
use of com.google.javascript.jscomp.testing.TestExternsBuilder in project closure-compiler by google.
the class MultiPassTest method testDestructuringInsideArrowFunction.
@Test
public void testDestructuringInsideArrowFunction() {
setDestructuringArrowFunctionOptions();
test(externs(new TestExternsBuilder().addJSCompLibraries().addConsole().build()), srcs(lines("var x, a, b;", "x = (() => {console.log(); return [a,b] = [1,2];})()")), expected(lines("var x, a, b;", "x = function () {", " console.log();", " return function () {", " let $jscomp$destructuring$var0 = [1,2];", " var $jscomp$destructuring$var1 = ", "$jscomp.makeIterator($jscomp$destructuring$var0);", " a = $jscomp$destructuring$var1.next().value;", " b = $jscomp$destructuring$var1.next().value;", " return $jscomp$destructuring$var0;", " } ();", "} ();")));
}
use of com.google.javascript.jscomp.testing.TestExternsBuilder in project closure-compiler by google.
the class RemoveUnusedCodeTest method testRemoveUnusedPolyfills_global_untyped.
@Test
public void testRemoveUnusedPolyfills_global_untyped() {
final String mapPolyfill = "$jscomp.polyfill('Map', function() {}, 'es6', 'es3');";
PolyfillRemovalTester tester = new PolyfillRemovalTester().addExterns(new TestExternsBuilder().addConsole().addExtra(JSCOMP_POLYFILL, "/** @constructor */ function Map() {}").build()).addPolyfill(mapPolyfill);
// unused polyfill is removed
tester.expectPolyfillsRemovedTest("console.log()", mapPolyfill);
// used polyfill is not removed
tester.expectNoRemovalTest("console.log(new Map())");
// Local names shadowing global polyfills are not themselves polyfill references.
tester.expectPolyfillsRemovedTest(lines(//
"console.log(function(Map) {", " console.log(new Map());", "});"), mapPolyfill);
}
use of com.google.javascript.jscomp.testing.TestExternsBuilder in project closure-compiler by google.
the class RemoveUnusedCodeTest method testRemoveUnusedPolyfills_guardedGlobals.
@Test
public void testRemoveUnusedPolyfills_guardedGlobals() {
final String mapPolyfill = "$jscomp.polyfill('Map', function() {}, 'es6', 'es3');";
PolyfillRemovalTester tester = new PolyfillRemovalTester().addExterns(new TestExternsBuilder().addConsole().addExtra(JSCOMP_POLYFILL, "/** @constructor */ function Map() {}", "/** @constructor */ function Promise() {}").build()).addPolyfill(mapPolyfill);
tester.expectPolyfillsRemovedTest(lines(//
"if (typeof Map !== 'undefined') {", " console.log(Map);", "}"), mapPolyfill);
tester.expectPolyfillsRemovedTest(lines(//
"if (Map) {", " console.log(Map);", "}"), mapPolyfill);
final String promisePolyfill = "$jscomp.polyfill('Promise', function() {}, 'es6', 'es3');";
tester.addPolyfill(promisePolyfill);
tester.expectPolyfillsRemovedTest(lines(// Map is guarded, but Promise is not, so only Map is removed.
"if (typeof Map !== 'undefined') {", " console.log(Map);", " console.log(Promise);", "}"), mapPolyfill);
}
use of com.google.javascript.jscomp.testing.TestExternsBuilder in project closure-compiler by google.
the class RemoveUnusedCodeTest method testRemoveUnusedPolyfills_globalWithPrototypePolyfill_untyped.
@Test
public void testRemoveUnusedPolyfills_globalWithPrototypePolyfill_untyped() {
final String promisePolyfill = "$jscomp.polyfill('Promise', function() {}, 'es6', 'es3');";
final String finallyPolyfill = "$jscomp.polyfill('Promise.prototype.finally', function() {}, 'es8', 'es3');";
PolyfillRemovalTester tester = new PolyfillRemovalTester().addExterns(//
new TestExternsBuilder().addPromise().addConsole().addExtra(JSCOMP_POLYFILL).build()).addPolyfill(promisePolyfill).addPolyfill(finallyPolyfill);
// Both the base polyfill and the extra method are removed when unused.
tester.expectPolyfillsRemovedTest("console.log();", promisePolyfill, finallyPolyfill);
// The extra method polyfill is removed if not used, even when the base is retained.
tester.expectPolyfillsRemovedTest("console.log(Promise.resolve());", finallyPolyfill);
// Promise is guarded by an optional chain.
tester.expectPolyfillsRemovedTest("console.log(Promise?.resolve());", promisePolyfill, finallyPolyfill);
// Can't remove finally without type information
tester.expectPolyfillsRemovedTest(lines(//
"", "const p = {finally() {}};", "p.finally();"), // it would actually prevent the Promise polyfill from being removed.
promisePolyfill);
// `finally` is guarded by an optional chain
tester.expectPolyfillsRemovedTest(lines(//
"", "const p = {finally() {}};", "p.finally?.();"), promisePolyfill, finallyPolyfill);
// Retain both the base and the extra method when both are used.
tester.expectNoRemovalTest("console.log(Promise.resolve().finally(() => {}));");
tester.expectPolyfillsRemovedTest("console.log(Promise?.resolve()?.finally(() => {}));", // finally is not guarded
promisePolyfill);
tester.expectPolyfillsRemovedTest("console.log(Promise?.resolve().finally?.(() => {}));", promisePolyfill, // both are guarded
finallyPolyfill);
// TODO(b/163394833): Note that this behavior could result in the Promise polyfill being
// removed, then the Promise.prototype.finally polyfill code having nowhere to hang its value.
// This is consistent with the way guarding with `&&` would behave, as demonstrated by the
// following test case.
// NOTE: In reality the Promise.prototype.finally polyfill references Promise, so
// it would actually prevent the Promise polyfill from being removed.
tester.expectPolyfillsRemovedTest("console.log(Promise?.resolve().finally(() => {}));", // only Promise guarded by optional chain
promisePolyfill);
tester.expectPolyfillsRemovedTest("console.log(Promise && Promise.resolve().finally(() => {}));", // only Promise guarded by optional chain
promisePolyfill);
tester.expectPolyfillsRemovedTest("console.log(Promise.resolve().finally?.(() => {}));", // only `finally` guarded by optional chain
finallyPolyfill);
// The base polyfill is removed and the extra method retained if the constructor never shows up
// anywhere in the source code. NOTE: this is probably the wrong thing to do. This situation
// should only be possible if async function transpilation happens *after* RemoveUnusedCode
// (since we have an async function). The fact that we inserted the Promise polyfill in the
// first case indicates the output language is < ES6. When that later transpilation occurs, we
// will end up adding uses of the Promise constructor. We need to keep this in mind when moving
// transpilation after optimizations.
tester.expectPolyfillsRemovedTest(lines(//
"", "async function f() {}", "f().finally(() => {});", ""), promisePolyfill);
}
Aggregations