/*
* Copyright 2015 The Closure Compiler Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.javascript.jscomp;
import static com.google.javascript.jscomp.CheckRequiresForConstructors.EXTRA_REQUIRE_WARNING;
import static com.google.javascript.jscomp.CheckRequiresForConstructors.MISSING_REQUIRE_WARNING;
/**
* Tests for {@link CheckRequiresForConstructors} in single-file mode.
*/
public final class SingleFileCheckRequiresTest extends Es6CompilerTestCase {
@Override
protected CompilerOptions getOptions(CompilerOptions options) {
options.setWarningLevel(DiagnosticGroups.MISSING_REQUIRE, CheckLevel.ERROR);
options.setWarningLevel(DiagnosticGroups.EXTRA_REQUIRE, CheckLevel.ERROR);
return super.getOptions(options);
}
@Override
protected CompilerPass getProcessor(final Compiler compiler) {
return new CheckRequiresForConstructors(compiler,
CheckRequiresForConstructors.Mode.SINGLE_FILE);
}
public void testReferenceToSingleName() {
testSame("new Foo();");
testSame("new Array();");
testSame("new Error();");
}
public void testCtorExtendsSingleName() {
testSame("/** @constructor @extends {Foo} */ function MyFoo() {}");
testSame("/** @constructor @extends {Error} */ function MyError() {}");
testSame("/** @constructor @extends {Array} */ function MyArray() {}");
}
public void testClassExtendsSingleName() {
testSameEs6("class MyFoo extends Foo {}");
testSameEs6("class MyError extends Error {}");
testSameEs6("class MyArray extends Array {}");
}
public void testReferenceToQualifiedName() {
testError(
LINE_JOINER.join(
"goog.require('x.y.z');",
"goog.require('bar.Abc');",
"new x.y.z();",
"new bar.Abc();",
"new bar.Foo();"),
MISSING_REQUIRE_WARNING);
}
// Since there are no goog.require()s for any bar.* names, assume that bar
// is a "non-Closurized" namespace, i.e. that all bar.* names come from the externs.
public void testReferenceToQualifiedName_nonClosurizedNamespace() {
testSame(
LINE_JOINER.join(
"goog.require('x.y.z');",
"new x.y.z();",
"new bar.Foo();"));
}
public void testReferenceToUnqualifiedName() {
testSameEs6(
LINE_JOINER.join(
"goog.module('a.b.c');",
"var z = goog.require('x.y.z');",
"",
"exports = { foobar : z };"));
testSameEs6(
LINE_JOINER.join(
"goog.module('a.b.c');",
"var {z} = goog.require('x.y');",
"",
"exports = { foobar : z };"));
testSameEs6(
LINE_JOINER.join(
"import {z} from 'x.y'",
"",
"export var foobar = z;"));
testSameEs6(
LINE_JOINER.join(
"import z from 'x.y.z'",
"",
"export var foobar = z;"));
}
public void testExtraRequire() {
testErrorEs6("goog.require('foo.Bar');", EXTRA_REQUIRE_WARNING);
}
public void testUnqualifiedRequireUsedInJSDoc() {
testSameEs6("goog.require('Bar'); /** @type {Bar} */ var x;");
}
public void testUnqualifiedImportUsedInJSDoc() {
testSameEs6("import { Something } from 'somewhere'; /** @type {Something} */ var x;");
}
public void testReferenceToSingleNameWithRequire() {
testSameEs6("goog.require('Foo'); new Foo();");
}
public void testReferenceInDefaultParam() {
testSameEs6("function func( a = new Bar() ){}; func();");
}
public void testReferenceInDestructuringParam() {
testSameEs6("var {a = new Bar()} = b;");
}
public void testPassForwardDeclareInModule() {
testSame(
LINE_JOINER.join(
"goog.module('example');",
"",
"var Event = goog.forwardDeclare('goog.events.Event');",
"",
"/**",
" * @param {!Event} event",
" */",
"function listener(event) {",
" alert(event);",
"}",
"",
"exports = listener;"));
}
public void testFailForwardDeclareInModule() {
testError(
LINE_JOINER.join(
"goog.module('example');",
"",
"var Event = goog.forwardDeclare('goog.events.Event');",
"var Unused = goog.forwardDeclare('goog.events.Unused');",
"",
"/**",
" * @param {!Event} event",
" */",
"function listener(event) {",
" alert(event);",
"}",
"",
"exports = listener;"),
EXTRA_REQUIRE_WARNING);
}
public void testPassForwardDeclare() {
testSame(
LINE_JOINER.join(
"goog.forwardDeclare('goog.events.Event');",
"",
"/**",
" * @param {!goog.events.Event} event",
" */",
"function listener(event) {",
" alert(event);",
"}"));
}
public void testFailForwardDeclare() {
testError(
LINE_JOINER.join(
"goog.forwardDeclare('goog.events.Event');",
"goog.forwardDeclare('goog.events.Unused');",
"",
"/**",
" * @param {!goog.events.Event} event",
" */",
"function listener(event) {",
" alert(event);",
"}"),
EXTRA_REQUIRE_WARNING);
}
}