diff --git a/src/com/google/javascript/refactoring/RefasterJs.java b/src/com/google/javascript/refactoring/RefasterJs.java deleted file mode 100644 index 4fcb8f271c4..00000000000 --- a/src/com/google/javascript/refactoring/RefasterJs.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright 2014 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.refactoring; - -import static com.google.common.base.Preconditions.checkArgument; - -import com.google.common.base.Preconditions; -import com.google.common.base.Splitter; -import com.google.common.base.Strings; -import com.google.javascript.jscomp.CommandLineRunner; -import com.google.javascript.jscomp.CompilerOptions; -import com.google.javascript.jscomp.ErrorManager; -import com.google.javascript.jscomp.TypeMatchingStrategy; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.TreeSet; -import java.util.logging.Level; -import java.util.logging.Logger; -import org.kohsuke.args4j.Argument; -import org.kohsuke.args4j.CmdLineParser; -import org.kohsuke.args4j.Option; -import org.kohsuke.args4j.spi.BooleanOptionHandler; - -/** - * Main binary that drives a RefasterJS refactoring. - */ -final class RefasterJs { - - @Option(name = "--help", - hidden = true, - handler = BooleanOptionHandler.class, - usage = "Show instructions for how to use RefasterJS") - private boolean displayHelp = false; - - @Option( - name = "--inputs", - usage = "List of input files for the refactoring. You may also use glob patterns to " - + "match files. For example, use --js='**.js' --js='!**_test.js' " - + "to recursively include all js files that do not end in _test.js") - private List inputs = new ArrayList<>(); - - @Option(name = "--externs", usage = "List of externs files to use in the compilation.") - private List externs = new ArrayList<>(); - - @Option( - name = "--refasterjs_template", - usage = "Location of the JS file to use as the RefasterJS template.") - private String refasterJsTemplate = null; - - @Option(name = "--env", - usage = "Which set of externs to include. Defaults to BROWSER.") - private CompilerOptions.Environment environment = - CompilerOptions.Environment.BROWSER; - - @Option(name = "--type_matching", - usage = "Which type matching strategy to use. Defaults to SUBTYPES.") - private TypeMatchingStrategy typeMatchingStrategy = TypeMatchingStrategy.SUBTYPES; - - @Option(name = "--dry_run", - usage = "Use this to display what changes would be made without applying the changes.") - private boolean dryRun = false; - - @Option(name = "--verbose", usage = "Use this to print verbose statements from RefasterJS.") - private boolean verbose = false; - - @Argument - private List arguments = new ArrayList<>(); - - private void doMain(String[] args) throws Exception { - CmdLineParser parser = new CmdLineParser(this); - parser.parseArgument(args); - if (args.length < 1 || displayHelp) { - CmdLineParser p = new CmdLineParser(this); - p.printUsage(System.out); - return; - } - checkArgument( - !Strings.isNullOrEmpty(refasterJsTemplate), "--refasterjs_template must be provided"); - List fileInputs = getInputs(); - checkArgument( - !fileInputs.isEmpty(), "At least one input must be provided in the --inputs flag."); - for (String input : fileInputs) { - Preconditions.checkArgument( - new File(input).exists(), "Input file %s does not exist.", input); - } - - if (!verbose) { - // This is done here instead of using the Compiler#setLoggingLevel function since the - // Compiler is created and then run inside of RefactoringDriver. - Logger errorManagerLogger = Logger.getLogger("com.google.javascript.jscomp"); - errorManagerLogger.setLevel(Level.OFF); - } - - RefasterJsScanner scanner = new RefasterJsScanner(); - scanner.setTypeMatchingStrategy(typeMatchingStrategy); - scanner.loadRefasterJsTemplate(refasterJsTemplate); - CompilerOptions options = new CompilerOptions(); - options.setEnvironment(environment); - RefactoringDriver driver = - new RefactoringDriver.Builder() - .addExterns(CommandLineRunner.getBuiltinExterns(environment)) - .addExternsFromFile(getExterns()) - .addInputsFromFile(fileInputs) - .build(); - System.out.println("Compiling JavaScript code and searching for suggested fixes."); - // TODO(bangert): allow picking a non-default choice in RefasterJS, e.g. via a switch. - List fixes = driver.drive(scanner); - - if (!verbose) { - // When running in quiet mode, the Compiler's error manager will not have printed - // this information itself. - ErrorManager errorManager = driver.getCompiler().getErrorManager(); - System.out.println("Compiler results: " + errorManager.getErrorCount() - + " errors and " + errorManager.getWarningCount() + " warnings."); - } - System.out.println("Found " + fixes.size() + " suggested fixes."); - if (dryRun) { - if (!fixes.isEmpty()) { - System.out.println("SuggestedFixes: " + fixes); - } - } else { - Set affectedFiles = new TreeSet<>(); - for (SuggestedFix fix : fixes) { - affectedFiles.addAll(fix.getReplacements().keySet()); - } - System.out.println("Modifying affected files: " + affectedFiles); - ApplySuggestedFixes.applySuggestedFixesToFiles(fixes); - } - } - - private List getInputs() throws IOException { - Set patterns = new HashSet<>(); - // The args4j library can't handle multiple files provided within the same flag option, - // like --inputs=file1.js,file2.js so handle that here. - Splitter commaSplitter = Splitter.on(','); - for (String input : inputs) { - patterns.addAll(commaSplitter.splitToList(input)); - } - patterns.addAll(arguments); - return CommandLineRunner.findJsFiles(patterns); - } - - private List getExterns() throws IOException { - Set patterns = new HashSet<>(); - // The args4j library can't handle multiple files provided within the same flag option, - // like --externs=file1.js,file2.js so handle that here. - Splitter commaSplitter = Splitter.on(','); - for (String extern : externs) { - patterns.addAll(commaSplitter.splitToList(extern)); - } - return CommandLineRunner.findJsFiles(patterns); - } - - public static void main(String[] args) throws Exception { - new RefasterJs().doMain(args); - } -} diff --git a/src/com/google/javascript/refactoring/RefasterJsScanner.java b/src/com/google/javascript/refactoring/RefasterJsScanner.java deleted file mode 100644 index 18f39232c99..00000000000 --- a/src/com/google/javascript/refactoring/RefasterJsScanner.java +++ /dev/null @@ -1,405 +0,0 @@ -/* - * Copyright 2014 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.refactoring; - -import static com.google.common.base.Preconditions.checkState; -import static com.google.common.collect.ImmutableList.toImmutableList; -import static java.nio.charset.StandardCharsets.UTF_8; - -import com.google.common.base.Preconditions; -import com.google.common.base.Strings; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSortedMap; -import com.google.common.io.Files; -import com.google.common.io.Resources; -import com.google.javascript.jscomp.AbstractCompiler; -import com.google.javascript.jscomp.JsAst; -import com.google.javascript.jscomp.NodeUtil; -import com.google.javascript.jscomp.SourceFile; -import com.google.javascript.jscomp.TypeMatchingStrategy; -import com.google.javascript.rhino.IR; -import com.google.javascript.rhino.JSDocInfo; -import com.google.javascript.rhino.Node; -import java.io.File; -import java.io.IOException; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.SortedMap; -import java.util.TreeMap; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Stream; - -/** - * Class that drives the RefasterJs refactoring by matching against a provided - * template JS file and then applying a transformation based off the template - * JS. - */ -public final class RefasterJsScanner extends Scanner { - /** The JS code that contains the RefasterJs templates. */ - private String templateJs; - - /** - * The type matching strategy to use when matching templates. - * - *

Defaults to {@link TypeMatchingStrategy#SUBTYPES}. - */ - private TypeMatchingStrategy typeMatchingStrategy = TypeMatchingStrategy.SUBTYPES; - - /** - * Each 'before' template has multiple RefasterJsTemplate instances that correspond to the - * multiple alternative fixes. - */ - private LinkedHashMap> templates; - - /** The RefasterJsTemplates that matched the last match. */ - private ImmutableList matchedTemplates; - - public RefasterJsScanner() { - this.templateJs = null; - } - - /** - * Loads the RefasterJs template. This must be called before the scanner is used. - */ - public void loadRefasterJsTemplate(String refasterjsTemplate) throws IOException { - checkState( - templateJs == null, "Can't load RefasterJs template since a template is already loaded."); - this.templateJs = - Thread.currentThread().getContextClassLoader().getResource(refasterjsTemplate) != null - ? Resources.toString(Resources.getResource(refasterjsTemplate), UTF_8) - : Files.asCharSource(new File(refasterjsTemplate), UTF_8).read(); - } - - /** - * Sets the type matching strategy to use when matching templates. - * - *

Defaults to {@link TypeMatchingStrategy#SUBTYPES}. - */ - public void setTypeMatchingStrategy(TypeMatchingStrategy typeMatchingStrategy) { - this.typeMatchingStrategy = typeMatchingStrategy; - } - - /** - * Loads the RefasterJs template. This must be called before the scanner is used. - */ - public void loadRefasterJsTemplateFromCode(String refasterJsTemplate) throws IOException { - checkState( - templateJs == null, "Can't load RefasterJs template since a template is already loaded."); - this.templateJs = refasterJsTemplate; - } - - /** - * Clears the RefasterJs templates used for comparison. This function should be called if this - * class is going to be used with multiple Compiler objects since type comparison is dependent - * on the compiler used to generate the types. - */ - public void clearTemplates() { - templates = null; - matchedTemplates = null; - } - - @Override public boolean matches(Node node, NodeMetadata metadata) { - if (templates == null) { - try { - initialize(metadata.getCompiler()); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - matchedTemplates = null; - for (Map.Entry> e : templates.entrySet()) { - if (e.getKey().matches(node, metadata)) { - this.matchedTemplates = e.getValue(); - return true; - } - } - return false; - } - - @Override - public ImmutableList processMatch(Match match) { - SuggestedFix.Builder defaultFix = null; - for (RefasterJsTemplate matchedTemplate : matchedTemplates) { - SuggestedFix.Builder fix = new SuggestedFix.Builder(); - // Only replace the original source with a version serialized from the AST if the after - // template - // is actually different. Otherwise, we might just add churn (e.g. single quotes into double - // quotes and whitespace). - if (matchedTemplate - .beforeTemplate - .getLastChild() - .isEquivalentTo(matchedTemplate.afterTemplate.getLastChild())) { - return ImmutableList.of(); - } - - Node script = NodeUtil.getEnclosingScript(match.getNode()); - ScriptMetadata scriptMetadata = ScriptMetadata.create(script, match.getMetadata()); - - for (String require : matchedTemplate.getGoogRequiresToAdd()) { - if (scriptMetadata.getAlias(require) == null) { - fix.addGoogRequire(match, require, scriptMetadata); - } - } - - // Re-match to compute getTemplateNodeToMatchMap. - Preconditions.checkState( - matchedTemplate.matcher.matches(match.getNode(), match.getMetadata()), - "Matcher for %s did not match a second time", - matchedTemplate.beforeTemplate); - - Node newNode = - transformNode( - matchedTemplate.afterTemplate.getLastChild(), - matchedTemplate.matcher.getTemplateNodeToMatchMap(), - scriptMetadata); - Node nodeToReplace = match.getNode(); - fix.attachMatchedNodeInfo(nodeToReplace, match.getMetadata().getCompiler()); - fix.replace(nodeToReplace, newNode, match.getMetadata().getCompiler()); - // If the template is a multiline tcs emplate, make sure to delete the same number of sibling - // nodes as the template has. - Node n = match.getNode().getNext(); - int count = matchedTemplate.beforeTemplate.getLastChild().getChildCount(); - for (int i = 1; i < count; i++) { - Preconditions.checkNotNull( - n, - "Found mismatched sibling count between before template and matched node.\n" - + "Template: %s to %s\nMatch: %s", - matchedTemplate.beforeTemplate.getLastChild(), - matchedTemplate.afterTemplate.getLastChild(), - match.getNode()); - fix.delete(n); - n = n.getNext(); - } - - for (String require : matchedTemplate.getGoogRequiresToRemove()) { - fix.removeGoogRequire(match, require); - } - - if (defaultFix == null) { - defaultFix = fix; - } else { - defaultFix.addAlternative(fix.build()); - } - } - return ImmutableList.of(defaultFix.build()); - } - - /** - * Transforms the template node to a replacement node by mapping the template names to the ones - * that were matched against in the JsSourceMatcher. - */ - private Node transformNode( - Node templateNode, Map templateNodeToMatchMap, ScriptMetadata scriptMetadata) { - Node clone = templateNode.cloneNode(); - if (templateNode.isName()) { - String name = templateNode.getString(); - if (templateNodeToMatchMap.containsKey(name)) { - Node templateMatch = templateNodeToMatchMap.get(name); - Preconditions.checkNotNull(templateMatch, "Match for %s is null", name); - if (templateNode.getParent().isVar()) { - // Var declarations should only copy the variable name from the saved match, but the rest - // of the subtree should come from the template node. - clone.setString(templateMatch.getString()); - } else { - return templateMatch.cloneTree(); - } - } - } else if (templateNode.isCall() - && templateNode.getBooleanProp(Node.FREE_CALL) - && templateNode.getFirstChild().isName()) { - String name = templateNode.getFirstChild().getString(); - if (templateNodeToMatchMap.containsKey(name)) { - // If this function call matches a template parameter, don't treat it as a free call. - // This mirrors the behavior in the TemplateAstMatcher as well as ensures the code - // generator doesn't generate code like "(0,fn)()". - clone.putBooleanProp(Node.FREE_CALL, false); - } - } - if (templateNode.isQualifiedName()) { - String name = templateNode.getQualifiedName(); - String alias = scriptMetadata.getAlias(name); - if (alias != null && !name.equals(alias)) { - return IR.name(alias); - } - } - for (Node child = templateNode.getFirstChild(); child != null; child = child.getNext()) { - clone.addChildToBack(transformNode(child, templateNodeToMatchMap, scriptMetadata)); - } - return clone; - } - - /** - * Initializes the Scanner class by loading the template JS file, compiling it, and then - * finding all matching RefasterJs template functions in the file. - */ - void initialize(AbstractCompiler compiler) throws Exception { - checkState( - !Strings.isNullOrEmpty(templateJs), - "The template JS must be loaded before the scanner is used. " - + "Make sure that the template file is not empty."); - Node scriptRoot = new JsAst(SourceFile.fromCode( - "template", templateJs)).getAstRoot(compiler); - - // The before-templates are kept in a LinkedHashMap, to ensure that they are later iterated - // over in the order in which they appear in the template JS file. - LinkedHashMap beforeTemplates = new LinkedHashMap<>(); - Map> afterTemplates = new HashMap<>(); - Set hasChoices = new HashSet<>(); - for (Node templateNode = scriptRoot.getFirstChild(); - templateNode != null; - templateNode = templateNode.getNext()) { - if (templateNode.isFunction()) { - String fnName = templateNode.getFirstChild().getQualifiedName(); - if (fnName.startsWith("before_")) { - String templateName = fnName.substring("before_".length()); - Preconditions.checkState( - !beforeTemplates.containsKey(templateName), - "Found existing template with the same name: %s", beforeTemplates.get(templateName)); - checkState( - templateNode.getLastChild().hasChildren(), - "Before templates are not allowed to be empty!"); - beforeTemplates.put(templateName, templateNode); - } else if (fnName.startsWith("after_option_")) { - Matcher m = AFTER_CHOICE_PATTERN.matcher(fnName); - checkState(m.matches(), "Template name %s must match pattern after_option_\\d*_", fnName); - int optionNumber = Integer.parseInt(m.group(1)); - String templateName = m.group(2); - if (!afterTemplates.containsKey(templateName)) { - afterTemplates.put(templateName, new TreeMap<>()); - hasChoices.add(templateName); - } - checkState( - hasChoices.contains(templateName), - "Template %s can only be mixed with other after_option_ templates"); - checkState( - !afterTemplates.get(templateName).containsKey(optionNumber), - "Found duplicate template for %s, assign unique indexes for options", - fnName); - afterTemplates.get(templateName).put(optionNumber, templateNode); - } else if (fnName.startsWith("after_")) { - String templateName = fnName.substring("after_".length()); - Preconditions.checkState( - !afterTemplates.containsKey(templateName), - "Found existing template with the same name: %s", afterTemplates.get(templateName)); - afterTemplates.put(templateName, ImmutableSortedMap.of(0, templateNode)); - } else if (fnName.startsWith("do_not_change_")) { - String templateName = fnName.substring("do_not_change_".length()); - Preconditions.checkState( - !beforeTemplates.containsKey(templateName), - "Found existing template with the same name: %s", - beforeTemplates.get(templateName)); - Preconditions.checkState( - !afterTemplates.containsKey(templateName), - "Found existing template with the same name: %s", - afterTemplates.get(templateName)); - beforeTemplates.put(templateName, templateNode); - afterTemplates.put(templateName, ImmutableSortedMap.of(0, templateNode)); - } - } - } - - checkState( - !beforeTemplates.isEmpty(), - "Did not find any RefasterJs templates! Make sure that there are 2 functions defined " - + "with the same name, one with a \"before_\" prefix and one with a \"after_\" prefix"); - - // TODO(bangert): Get ImmutableLinkedMap into Guava? - this.templates = new LinkedHashMap<>(); - for (String templateName : beforeTemplates.keySet()) { - Preconditions.checkState( - afterTemplates.containsKey(templateName) && !afterTemplates.get(templateName).isEmpty(), - "Found before template without at least one corresponding after " - + " template. Make sure there is an after_%s or after_option_1_%s function defined.", - templateName, - templateName); - ImmutableList.Builder builder = ImmutableList.builder(); - for (Node afterTemplateOption : afterTemplates.get(templateName).values()) { - builder.add( - new RefasterJsTemplate( - compiler, - typeMatchingStrategy, - beforeTemplates.get(templateName), - afterTemplateOption)); - } - ImmutableList afterOptions = builder.build(); - this.templates.put(afterOptions.get(0).matcher, afterOptions); - } - } - - private static final Pattern AFTER_CHOICE_PATTERN = Pattern.compile("^after_option_(\\d*)_(.*)"); - - /** Class that holds the before and after templates for a given RefasterJs refactoring. */ - private static class RefasterJsTemplate { - private static final Pattern ADD_GOOG_REQUIRE_PATTERN = - Pattern.compile("\\+require\\s+\\{([^}]+)\\}"); - private static final Pattern REMOVE_GOOG_REQUIRE_PATTERN = - Pattern.compile("-require\\s+\\{([^}]+)\\}"); - - final JsSourceMatcher matcher; - final Node beforeTemplate; - final Node afterTemplate; - - RefasterJsTemplate( - AbstractCompiler compiler, - TypeMatchingStrategy typeMatchingStrategy, - Node beforeTemplate, - Node afterTemplate) { - this.matcher = new JsSourceMatcher(compiler, beforeTemplate, typeMatchingStrategy); - this.beforeTemplate = beforeTemplate; - this.afterTemplate = afterTemplate; - } - - List getGoogRequiresToAdd() { - return getGoogRequiresFromPattern(ADD_GOOG_REQUIRE_PATTERN); - } - - List getGoogRequiresToRemove() { - return getGoogRequiresFromPattern(REMOVE_GOOG_REQUIRE_PATTERN); - } - - private ImmutableList getGoogRequiresFromPattern(Pattern pattern) { - return Stream.concat( - getGoogRequiresFromNode(pattern, beforeTemplate).stream(), - getGoogRequiresFromNode(pattern, afterTemplate).stream()) - .distinct() - .collect(toImmutableList()); - } - - private static ImmutableList getGoogRequiresFromNode( - Pattern pattern, Node beforeTemplate) { - JSDocInfo jsDoc = NodeUtil.getBestJSDocInfo(beforeTemplate); - if (jsDoc == null) { - return ImmutableList.of(); - } - String jsDocContent = jsDoc.getOriginalCommentString(); - if (jsDocContent == null) { - return ImmutableList.of(); - } - ImmutableList.Builder requires = ImmutableList.builder(); - Matcher m = pattern.matcher(jsDocContent); - while (m.find()) { - requires.add(m.group(1)); - } - return requires.build(); - } - } -} diff --git a/src/com/google/javascript/refactoring/examples/refasterjs/array_indexof_to_includes.js b/src/com/google/javascript/refactoring/examples/refasterjs/array_indexof_to_includes.js deleted file mode 100644 index 7574e0edbd8..00000000000 --- a/src/com/google/javascript/refactoring/examples/refasterjs/array_indexof_to_includes.js +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright 2017 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. - */ - -/** - * @fileoverview RefasterJS templates for replacing the usage of - * Array.prototype.indexOf to determine whether an element is in the array or - * not with Array.prototype.includes. - * - * Note that Array.prototype.includes handles NaN in a different way: - * [1, 2, NaN].includes(NaN); // true - * [1, 2, NaN].indexOf(NaN); // -1 - * - * Available in: - * - Chrome 47+ - * - Firefox 43+ - * - Edge 14+ - * - Opera 34+ - * - Safari 9+ - * - IE n/a - * - * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes - * - * This refactoring covers the most common cases in which this can be expressed: - * - * 'arr.includes(elem)' is equivalent to: - * - arr.indexOf(elem) != -1 - * - arr.indexOf(elem) !== -1 - * - arr.indexOf(elem) > -1 - * - arr.indexOf(elem) >= 0 - * - * '!arr.includes(elem)' is equivalent to: - * - arr.indexOf(elem) == -1 - * - arr.indexOf(elem) === -1 - * - arr.indexOf(elem) < 0 - */ - -// elem found in the array. - -/** - * @param {!Array} arr - * @param {*} elem - * @suppress {uselessCode} - */ -function before_indexOfNotEqualsMinusOne(arr, elem) { - arr.indexOf(elem) != -1; -} - -/** - * @param {!Array} arr - * @param {*} elem - */ -function after_indexOfNotEqualsMinusOne(arr, elem) { - arr.includes(elem); -} - -/** - * @param {!Array} arr - * @param {*} elem - * @suppress {uselessCode} - */ -function before_indexOfStronglyNotEqualsMinusOne(arr, elem) { - arr.indexOf(elem) !== -1; -} - -/** - * @param {!Array} arr - * @param {*} elem - */ -function after_indexOfStronglyNotEqualsMinusOne(arr, elem) { - arr.includes(elem); -} - -/** - * @param {!Array} arr - * @param {*} elem - * @suppress {uselessCode} - */ -function before_indexOfGreaterThanMinusOne(arr, elem) { - arr.indexOf(elem) > -1; -} - -/** - * @param {!Array} arr - * @param {*} elem - */ -function after_indexOfGreaterThanMinusOne(arr, elem) { - arr.includes(elem); -} - -/** - * @param {!Array} arr - * @param {*} elem - * @suppress {uselessCode} - */ -function before_indexOfGreaterThanOrEqualsZero(arr, elem) { - arr.indexOf(elem) >= 0; -} - -/** - * @param {!Array} arr - * @param {*} elem - */ -function after_indexOfGreaterThanOrEqualsZero(arr, elem) { - arr.includes(elem); -} - -// elem NOT found in the array. - -/** - * @param {!Array} arr - * @param {*} elem - * @suppress {uselessCode} - */ -function before_indexOfEqualsMinusOne(arr, elem) { - arr.indexOf(elem) == -1; -} - -/** - * @param {!Array} arr - * @param {*} elem - * @suppress {uselessCode} - */ -function after_indexOfEqualsMinusOne(arr, elem) { - !arr.includes(elem); -} - -/** - * @param {!Array} arr - * @param {*} elem - * @suppress {uselessCode} - */ -function before_indexOfStronglyEqualsMinusOne(arr, elem) { - arr.indexOf(elem) === -1; -} - -/** - * @param {!Array} arr - * @param {*} elem - * @suppress {uselessCode} - */ -function after_indexOfStronglyEqualsMinusOne(arr, elem) { - !arr.includes(elem); -} - -/** - * @param {!Array} arr - * @param {*} elem - * @suppress {uselessCode} - */ -function before_indexOfLessThanZero(arr, elem) { - arr.indexOf(elem) < 0; -} - -/** - * @param {!Array} arr - * @param {*} elem - * @suppress {uselessCode} - */ -function after_indexOfLessThanZero(arr, elem) { - !arr.includes(elem); -} - -/** - * @param {!Array} arr - * @param {*} elem - * @suppress {uselessCode} - */ -function before_bitwiseNot(arr, elem) { - ~arr.indexOf(elem); -} - -/** - * @param {!Array} arr - * @param {*} elem - * @suppress {uselessCode} - */ -function after_bitwiseNot(arr, elem) { - arr.includes(elem); -} diff --git a/src/com/google/javascript/refactoring/examples/refasterjs/array_prototype_slice_to_array_from.js b/src/com/google/javascript/refactoring/examples/refasterjs/array_prototype_slice_to_array_from.js deleted file mode 100644 index 01a109e4340..00000000000 --- a/src/com/google/javascript/refactoring/examples/refasterjs/array_prototype_slice_to_array_from.js +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2017 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. - */ - -/** - * @fileoverview RefasterJS templates for replacing the usage of - * Array.prototype.slice to convert an array-like object to an array with - * Array.from. - * - * Array.prototype.slice can be executed on the following types: - * - IArrayLike - Converts the array-like object to an Array. - * - Array - Creates a shallow copy of the array. - * - string - Creates an Array where each element is a character. - * 'abc' -> ['a', 'b', 'c'] - * - * 'Array.from(arrLike)' is equivalent to: - * - Array.prototype.slice(arrLike) - * - Array.prototype.slice(arrLike, 0) - * - * Available in: - * - Chrome 45+ - * - Firefox 32+ - * - Edge (Yes) - * - Opera (Yes) - * - Safari 9.0+ - * - IE n/a - * - * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from - */ - -/** - * @param {!(Array|IArrayLike|string)} arrLike - */ -function before_sliceNoArguments(arrLike) { - Array.prototype.slice.call(arrLike); -} - -/** - * @param {!(Array|IArrayLike|string)} arrLike - */ -function after_sliceNoArguments(arrLike) { - Array.from(arrLike); -} - -/** - * @param {!(Array|IArrayLike|string)} arrLike - */ -function before_sliceZero(arrLike) { - Array.prototype.slice.call(arrLike, 0); -} - -/** - * @param {!(Array|IArrayLike|string)} arrLike - */ -function after_sliceZero(arrLike) { - Array.from(arrLike); -} diff --git a/src/com/google/javascript/refactoring/examples/refasterjs/chai_expect_to_assert.js b/src/com/google/javascript/refactoring/examples/refasterjs/chai_expect_to_assert.js deleted file mode 100644 index a7616f5790d..00000000000 --- a/src/com/google/javascript/refactoring/examples/refasterjs/chai_expect_to_assert.js +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright 2017 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. - */ - -/** - * @fileoverview RefasterJS templates for converting from Chai assertions like - * - * expect(thing).to.be.true; - * - * to - * - * assert.isTrue(thing); - * - * TODO(tbreisacher): Expand this to include chai-jquery assertions as well: - * http://chaijs.com/plugins/chai-jquery/ - * - * Then, once it's in a good state, mention it at go/js-practices/testing#chai - */ - -/** - * @param {?} param - */ -function before_true(param) { - expect(param).to.be.true; -} - -/** - * @param {?} param - */ -function after_true(param) { - assert.isTrue(param); -} - -/** - * @param {?} param - */ -function before_not_true(param) { - expect(param).to.not.be.true; -} - -/** - * @param {?} param - */ -function after_not_true(param) { - assert.isNotTrue(param); -} - -/** - * @param {?} param - */ -function before_false(param) { - expect(param).to.be.false; -} - -/** - * @param {?} param - */ -function after_false(param) { - assert.isFalse(param); -} - -/** - * @param {?} param - */ -function before_not_false(param) { - expect(param).to.not.be.false; -} - -/** - * @param {?} param - */ -function after_not_false(param) { - assert.isNotFalse(param); -} - -/** - * @param {?} param - */ -function before_null(param) { - expect(param).to.be.null; -} - -/** - * @param {?} param - */ -function after_null(param) { - assert.isNull(param); -} - -/** - * @param {?} param - */ -function before_not_null(param) { - expect(param).to.not.be.null; -} - -/** - * @param {?} param - */ -function after_not_null(param) { - assert.isNotNull(param); -} - -/** - * @param {?} param - */ -function before_undefined(param) { - expect(param).to.be.undefined; -} - -/** - * @param {?} param - */ -function after_undefined(param) { - assert.isUndefined(param); -} - -/** - * @param {?} param - */ -function before_not_undefined(param) { - expect(param).to.not.be.undefined; -} - -/** - * @param {?} param - */ -function after_not_undefined(param) { - assert.isDefined(param); -} - -/** - * @param {?} param - */ -function before_ok(param) { - expect(param).to.be.ok; -} - -/** - * @param {?} param - */ -function after_ok(param) { - assert.isOk(param); -} - -/** - * @param {?} param - */ -function before_not_ok(param) { - expect(param).to.not.be.ok; -} - -/** - * @param {?} param - */ -function after_not_ok(param) { - assert.isNotOk(param); -} - -/** - * @param {?} param - * @param {?} param2 - */ -function before_to_equal(param, param2) { - expect(param).to.equal(param2); -} - -/** - * @param {?} param - * @param {?} param2 - */ -function after_to_equal(param, param2) { - assert.equal(param, param2); -} - -/** - * @param {?} param - * @param {?} param2 - */ -function before_to_not_equal(param, param2) { - expect(param).to.not.equal(param2); -} - -/** - * @param {?} param - * @param {?} param2 - */ -function after_to_not_equal(param, param2) { - assert.notEqual(param, param2); -} - -/** - * @param {?} param - * @param {?} param2 - */ -function before_not_to_equal(param, param2) { - expect(param).not.to.equal(param2); -} - -/** - * @param {?} param - * @param {?} param2 - */ -function after_not_to_equal(param, param2) { - assert.notEqual(param, param2); -} - -/** - * @param {?} param - * @param {?} param2 - */ -function before_to_deep_equal(param, param2) { - expect(param).to.deep.equal(param2); -} - -/** - * @param {?} param - * @param {?} param2 - */ -function after_to_deep_equal(param, param2) { - assert.deepEqual(param, param2); -} - -/** - * @param {?} param - * @param {?} param2 - */ -function before_to_not_deep_equal(param, param2) { - expect(param).to.not.deep.equal(param2); -} - -/** - * @param {?} param - * @param {?} param2 - */ -function after_to_not_deep_equal(param, param2) { - assert.notDeepEqual(param, param2); -} - -/** - * @param {?} param - * @param {?} param2 - */ -function before_is_an_instanceof(param, param2) { - expect(param).is.an.instanceof(param2); -} - -/** - * @param {?} param - * @param {?} param2 - */ -function after_is_an_instanceof(param, param2) { - assert.instanceOf(param, param2); -} - -/** - * @param {?} param - * @param {?} param2 - */ -function before_to_be_an_instanceof(param, param2) { - expect(param).to.be.an.instanceof(param2); -} - -/** - * @param {?} param - * @param {?} param2 - */ -function after_to_be_an_instanceof(param, param2) { - assert.instanceOf(param, param2); -} - -/** - * @param {?} param - * @param {!Array} param2 - */ -function before_to_be_oneOf(param, param2) { - expect(param).to.be.oneOf(param2); -} - -/** - * @param {?} param - * @param {!Array} param2 - */ -function after_to_be_oneOf(param, param2) { - assert.oneOf(param, param2); -} - -/** - * @param {!Array|string} param - * @param {?} param2 - */ -function before_to_contain(param, param2) { - expect(param).to.contain(param2); -} - -/** - * @param {!Array|string} param - * @param {?} param2 - */ -function after_to_contain(param, param2) { - assert.include(param, param2); -} - -/** - * @param {?} param - * @param {number} param2 - */ -function before_to_have_lengthOf(param, param2) { - expect(param).to.have.lengthOf(param2); -} - -/** - * @param {?} param - * @param {number} param2 - */ -function after_to_have_lengthOf(param, param2) { - assert.lengthOf(param, param2); -} diff --git a/src/com/google/javascript/refactoring/examples/refasterjs/fix_throw_error.js b/src/com/google/javascript/refactoring/examples/refasterjs/fix_throw_error.js deleted file mode 100644 index 56b5fa9f62a..00000000000 --- a/src/com/google/javascript/refactoring/examples/refasterjs/fix_throw_error.js +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2014 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. - */ - -/** - * @fileoverview RefasterJS template for fixing common mistakes when throwing - * errors. - */ - -/** - * People should not throw a string as an error since stack traces are not - * included when strings are thrown. - * @param {string} msg - */ -function before_DoNotThrowString(msg) { - throw msg; -} - -/** - * @param {string} msg - */ -function after_DoNotThrowString(msg) { - throw new Error(msg); -} - -/** - * throw Error and throw new Error are equivalent except that the latter is more - * clear that a new object is being constructed. - * @param {*} anyArg - */ -function before_ThrowNewError(anyArg) { - throw Error(anyArg); -} - -/** - * @param {*} anyArg - */ -function after_ThrowNewError(anyArg) { - throw new Error(anyArg); -} diff --git a/src/com/google/javascript/refactoring/examples/refasterjs/security/navigational_xss_sinks.js b/src/com/google/javascript/refactoring/examples/refasterjs/security/navigational_xss_sinks.js deleted file mode 100644 index 657bdc42788..00000000000 --- a/src/com/google/javascript/refactoring/examples/refasterjs/security/navigational_xss_sinks.js +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright 2016 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. - */ - -/** - * @fileoverview RefasterJS templates for replacing direct use of XSS-prone - * "navigational" DOM APIs with corresponding goog.dom.safe wrapper functions. - * - * Navigational APIs include: Assignments to the .href property, assignments to - * the .location property, and method invocations on the Location object. - * - * For benign URLs, the wraper functions (such as, - * goog.dom.safe.setLocationHref) simply forward the provided URL to the - * underlying DOM property. For malicious URLs (such as 'javascript:evil()') - * however, the URL is sanitized and replaced with an innocuous value. - * - * As such, using the safe wrapper prevents XSS vulnerabilities that would - * otherwise be present if the URL is derived from untrusted input. - * - * The suite of templates in this file relies on the fact that RefasterJS - * attempts matches in the order of the before-templates as specified in the - * file. For each property/method, there is a template that matches in a - * precisely typed context, followed by templates that match in more loosely - * typed contexts (e.g., where an argument type is nullable), followed by a - * "catch-all" template that matches in an un-typed context. The catch-all - * template's after-template includes a call to a dummy marker function to flag - * such matches for human review. - */ - -goog.require('goog.asserts'); -goog.require('goog.dom.safe'); - -/** - * A function that serves as a marker for code that requires human review after - * refactoring (e.g., code that resulted from refactoring of poorly typed - * source). It is declared here to allow this template file to compile; - * however it won't be declared in post-refactoring code and hence will - * intentionally cause a compilation error to flag such code for human review. - * @param {?} x - * @return {?} - */ -function requiresReview(x) { - return x; -} - -// -// Refactorings for assignments to the href property -// - - - -// String literal assignments are implicitly trusted (the URL was -// code-reviewed). - -/** - * @param {?} thing1 - * @param {string} string_literal_thing2 - */ -function before_setHrefStringLiteral(thing1, string_literal_thing2) { - thing1.href = string_literal_thing2; -} - -/** - * @param {?} thing1 - * @param {string} string_literal_thing2 - */ -function after_setHrefStringLiteral(thing1, string_literal_thing2) { - thing1.href = string_literal_thing2; -} - -// Refactorings for assignments to the href property of a Location object into -// use of the corresponding safe wrapper, goog.dom.safe.setLocationHref. -// -// The wrapper expects a non-nullable Location. The first template matches the -// non-nullable type exactly. The second template matches the nullable type, -// which is accounted for in the after-template using an assert to coerce the -// value to the non-nullable type. - -/** - * +require {goog.dom.safe} - * @param {!Location} loc The location object. - * @param {string} url The url. - */ -function before_setLocationHref(loc, url) { - loc.href = url; -} - -/** - * @param {!Location} loc The location object. - * @param {string} url The url. - */ -function after_setLocationHref(loc, url) { - goog.dom.safe.setLocationHref(loc, url); -} - -/** - * +require {goog.asserts} - * +require {goog.dom.safe} - * @param {Location|null|undefined} loc The location object. - * @param {string} url The url. - */ -function before_setLocationHrefNullable(loc, url) { - loc.href = url; -} - -/** - * @param {Location|null|undefined} loc The location object. - * @param {string} url The url. - */ -function after_setLocationHrefNullable(loc, url) { - goog.dom.safe.setLocationHref(goog.asserts.assert(loc), url); -} - - -// Refactorings for assignments to the href property of a HTMLAnchorElement -// object into use of the corresponding safe wrapper, -// goog.dom.safe.setAnchorHref. -// -// The wrapper expects a non-nullable HTMLAnchorElement. The first template -// matches the non-nullable type exactly. The second template matches the -// nullable type, which is accounted for in the after-template using an assert -// to coerce the value to the non-nullable type. - - -/** - * +require {goog.dom.safe} - * @param {!HTMLAnchorElement} anchor - * @param {string} url - */ -function before_setAnchorHref(anchor, url) { - anchor.href = url; -} - -/** - * @param {!HTMLAnchorElement} anchor - * @param {string} url - */ -function after_setAnchorHref(anchor, url) { - goog.dom.safe.setAnchorHref(anchor, url); -} - -/** - * +require {goog.asserts} - * +require {goog.dom.safe} - * @param {HTMLAnchorElement|null|undefined} anchor - * @param {string} url - */ -function before_setAnchorHrefNullable(anchor, url) { - anchor.href = url; -} - -/** - * @param {HTMLAnchorElement|null|undefined} anchor - * @param {string} url - */ -function after_setAnchorHrefNullable(anchor, url) { - goog.dom.safe.setAnchorHref(goog.asserts.assert(anchor), url); -} - - -// Template to rewrite assignments to an href property of a target of -// unknown type. This acts as a catch-all rule for assignments to href that have -// not been matched by the specifically-typed rules above. -// -// Since these matches are based on incomplete type information and hence -// possibly incorrect, they are flagged for human review. This is accomplished -// by inserting a call to a dummy marker function that is easily greppable for, -// and won't be defined in code under refactoring (i.e., will intentionally -// result in a compilation error). - -/** - * +require {goog.asserts} - * +require {goog.dom.safe} - * @param {?} thing1 - * @param {?} thing2 - */ -function before_setHrefUnknown(thing1, thing2) { - thing1.href = thing2; -} - -/** - * @param {?} thing1 - * @param {?} thing2 - */ -function after_setHrefUnknown(thing1, thing2) { - goog.dom.safe.setLocationHref( - goog.asserts.assertInstanceof(requiresReview(thing1), Location), thing2); -} - -// -// Refactorings for assignments to the .location property. This accounts for the -// implicit cast to !Location for assignments to this property. -// - -// String literal assignments are implicitly trusted (the URL was -// code-reviewed). - -/** - * @param {?} thing1 - * @param {string} string_literal_thing2 - */ -function do_not_change_setLocationStringLiteral(thing1, string_literal_thing2) { - thing1.location = string_literal_thing2; -} - -/** - * +require {goog.dom.safe} - * @param {?Window} win The window object. - * @param {string} url The url. - */ -function before_setWindowLocation(win, url) { - win.location = url; -} - -/** - * @param {?Window} win The window object. - * @param {string} url The url. - */ -function after_setWindowLocation(win, url) { - goog.dom.safe.setLocationHref(win.location, url); -} - -/** - * +require {goog.dom.safe} - * @param {?Document} doc - * @param {string} url - */ -function before_setDocumentLocation(doc, url) { - doc.location = url; -} - -/** - * @param {?Document} doc - * @param {string} url - */ -function after_setDocumentLocation(doc, url) { - goog.dom.safe.setLocationHref(doc.location, url); -} - -// Catch-all for matches in un-typed contexts. - -/** - * +require {goog.asserts} - * +require {goog.dom.safe} - * @param {?} thing1 - * @param {?} thing2 - */ -function before_setLocationUnknown(thing1, thing2) { - thing1.location = thing2; -} - -/** - * @param {?} thing1 - * @param {?} thing2 - */ -function after_setLocationUnknown(thing1, thing2) { - goog.dom.safe.setLocationHref( - goog.asserts.assertInstanceof(requiresReview(thing1), Window).location, - thing2); -} diff --git a/src/com/google/javascript/refactoring/examples/refasterjs/security/set_anchor_href.js b/src/com/google/javascript/refactoring/examples/refasterjs/security/set_anchor_href.js deleted file mode 100644 index 2856e93cddf..00000000000 --- a/src/com/google/javascript/refactoring/examples/refasterjs/security/set_anchor_href.js +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2014 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. - */ - -/** - * @fileoverview RefasterJS templates for replacing direct access to the - * HTMLAnchorElement.prototype.href DOM property with a call to the - * goog.dom.safe.setAnchorHref wrapper. - * - * For benign URLs, setAnchorHref simply forwards the provided URL to the - * underlying DOM property. For malicious URLs (such as 'javascript:evil()') - * however, the URL is sanitized and replaced with an innocuous value. - * - * As such, using the safe wrapper prevents XSS vulnerabilities that would - * otherwise be present if the URL is derived from untrusted input. - */ - -goog.require('goog.dom.safe'); - -/** - * @param {?} anchor - * @param {string} string_literal_url - */ -function do_not_change_stringLiteral(anchor, string_literal_url) { - anchor.href = string_literal_url; -} - -/** - * +require {goog.dom.safe} - * @param {!HTMLAnchorElement} anchor - * @param {string} url - */ -function before_setAnchorHref(anchor, url) { - anchor.href = url; -} - -/** - * @param {!HTMLAnchorElement} anchor - * @param {string} url - */ -function after_setAnchorHref(anchor, url) { - goog.dom.safe.setAnchorHref(anchor, url); -} diff --git a/src/com/google/javascript/refactoring/examples/refasterjs/security/set_element_href.js b/src/com/google/javascript/refactoring/examples/refasterjs/security/set_element_href.js deleted file mode 100644 index aeb9c2f0aca..00000000000 --- a/src/com/google/javascript/refactoring/examples/refasterjs/security/set_element_href.js +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2017 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. - */ - -/** - * @fileoverview RefasterJS templates for replacing direct access to the - * Element.prototype.href DOM property with a call to the - * goog.dom.safe.setAnchorHref and goog.dom.asserts. wrapper. - * Ignore assignments to HTMLAnchorElement.prototype.href. - * - * For benign URLs, setAnchorHref simply forwards the provided URL to the - * underlying DOM property. For malicious URLs (such as 'javascript:evil()') - * however, the URL is sanitized and replaced with an innocuous value. - * - * As such, using the safe wrapper prevents XSS vulnerabilities that would - * otherwise be present if the URL is derived from untrusted input. - */ - -goog.require('goog.asserts'); -goog.require('goog.dom.asserts'); -goog.require('goog.dom.safe'); - - -/** - * HTMLAnchorElement is handled in set_anchor_href.js - * @param {!HTMLAnchorElement} anchor - * @param {string} url - */ -function do_not_change_setAnchorHref(anchor, url) { - anchor.href = url; -} - -/** - * @param {?} anchor - * @param {string} string_literal_url - */ -function do_not_change_stringLiteral(anchor, string_literal_url) { - anchor.href = string_literal_url; -} - -/** - * Assume all Elements with href are actually HTMLAnchorElement but poorly - * typed. - * - * We insert a goog.dom.assert to make sure they are an Element. Tests will fail - * if it is a link element (which should use setLinkHrefAndRel). - */ - -/** - * +require {goog.dom.asserts} - * +require {goog.dom.safe} - * @param {!Element} anchor - * @param {!string} url - */ -function before_setElementHref(anchor, url) { - anchor.href = url; -} - - -/** - * @param {!Element} anchor - * @param {!string} url - */ -function after_setElementHref(anchor, url) { - goog.dom.safe.setAnchorHref( - goog.dom.asserts.assertIsHTMLAnchorElement(anchor), url); -} - -/** - * +require {goog.asserts} - * +require {goog.dom.asserts} - * +require {goog.dom.safe} - * @param {Element|null|undefined} anchor - * @param {!string} url - */ -function before_setElementHrefOptionalDefiniteUrl(anchor, url) { - anchor.href = url; -} - -/** - * @param {Element|null|undefined} anchor - * @param {!string} url - */ -function after_setElementHrefOptionalDefiniteUrl(anchor, url) { - goog.dom.safe.setAnchorHref( - goog.dom.asserts.assertIsHTMLAnchorElement(goog.asserts.assert(anchor)), - url); -} - -/** - * +require {goog.asserts} - * +require {goog.dom.asserts} - * +require {goog.dom.safe} - * @param {!Element} anchor - * @param {!string|null|undefined} url - */ -function before_setElementDefiniteHrefOptional(anchor, url) { - anchor.href = url; -} - - -/** - * @param {!Element} anchor - * @param {!string|null|undefined} url - */ -function after_setElementDefiniteHrefOptional(anchor, url) { - goog.dom.safe.setAnchorHref( - goog.dom.asserts.assertIsHTMLAnchorElement(anchor), - goog.asserts.assertString(url)); -} - -/** - * +require {goog.asserts} - * +require {goog.dom.asserts} - * +require {goog.dom.safe} - * @param {!Element|null|undefined} anchor - * @param {?} url - */ -function before_setElementHrefBothOptional(anchor, url) { - anchor.href = url; -} - - -/** - * @param {!Element|null|undefined} anchor - * @param {?} url - */ -function after_setElementHrefBothOptional(anchor, url) { - goog.dom.safe.setAnchorHref( - goog.dom.asserts.assertIsHTMLAnchorElement(goog.asserts.assert(anchor)), - goog.asserts.assertString(url)); -} diff --git a/src/com/google/javascript/refactoring/examples/refasterjs/security/set_location_href.js b/src/com/google/javascript/refactoring/examples/refasterjs/security/set_location_href.js deleted file mode 100644 index 5b50cf74132..00000000000 --- a/src/com/google/javascript/refactoring/examples/refasterjs/security/set_location_href.js +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2014 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. - */ - -/** - * @fileoverview RefasterJS templates for replacing direct access to the - * Location.prototype.href DOM property with a - * call to the goog.dom.safe.setLocationHref wrapper. - * - * For benign URLs, setLocationHref simply forwards the provided URL to the - * underlying DOM property. For malicious URLs (such as 'javascript:evil()') - * however, the URL is sanitized and replaced with an innocuous value. - * - * As such, using the safe wrapper prevents XSS vulnerabilities that would - * otherwise be present if the URL is derived from untrusted input. - */ - -goog.require('goog.asserts'); -goog.require('goog.dom.safe'); - -/** - * @param {?} loc - * @param {string} string_literal_thing2 - */ -function do_not_change_setHrefStringLiteral(loc, string_literal_thing2) { - loc.href = string_literal_thing2; -} - - -/** - * Replaces writes to Location.property.href with a call to the corresponding - * goog.dom.safe.setLocationHref wrapper. - * +require {goog.dom.safe} - * @param {!Location} loc The location object. - * @param {string} url The url. - */ -function before_setLocationHref(loc, url) { - loc.href = url; -} - -/** - * @param {!Location} loc The location object. - * @param {string} url The url. - */ -function after_setLocationHref(loc, url) { - goog.dom.safe.setLocationHref(loc, url); -} -/** - * Replaces writes to Location.property.href with a call to the corresponding - * goog.dom.safe.setLocationHref wrapper. - * +require {goog.asserts} - * +require {goog.dom.safe} - * @param {!Location} loc The location object. - * @param {?} url The url. - */ -function before_setLocationUntypedHref(loc, url) { - loc.href = url; -} - -/** - * @param {!Location} loc The location object. - * @param {?} url The url. - */ -function after_setLocationUntypedHref(loc, url) { - goog.dom.safe.setLocationHref(loc, goog.asserts.assertString(url)); -} diff --git a/src/com/google/javascript/refactoring/examples/refasterjs/security/set_window_location.js b/src/com/google/javascript/refactoring/examples/refasterjs/security/set_window_location.js deleted file mode 100644 index 70b676fd24c..00000000000 --- a/src/com/google/javascript/refactoring/examples/refasterjs/security/set_window_location.js +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2014 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. - */ - -/** - * @fileoverview RefasterJS templates for replacing direct access to - * the Window.prototype.location DOM property with a call to the - * goog.dom.safe.setLocationHref wrapper. - * - * For benign URLs, setLocationHref simply forwards the provided URL to the - * underlying DOM property. For malicious URLs (such as 'javascript:evil()') - * however, the URL is sanitized and replaced with an innocuous value. - * - * As such, using the safe wrapper prevents XSS vulnerabilities that would - * otherwise be present if the URL is derived from untrusted input. - */ - -goog.require('goog.asserts'); -goog.require('goog.dom.safe'); - -/** - * @param {?} thing1 - * @param {string} string_literal_thing2 - */ -function do_not_change_setLocationStringLiteral(thing1, string_literal_thing2) { - thing1.location = string_literal_thing2; -} - - -/** - * Replaces writes to Window.property.location with a call to the corresponding - * goog.dom.safe.setLocationHref wrapper. - * +require {goog.dom.safe} - * @param {?Window} win The window object. - * @param {string} url The url. - */ -function before_setWindowLocation(win, url) { - win.location = url; -} - -/** - * @param {?Window} win The window object. - * @param {string} url The url. - */ -function after_setWindowLocation(win, url) { - goog.dom.safe.setLocationHref(win.location, url); -} - -/** - * Replaces writes to Window.property.location with a call to the corresponding - * goog.dom.safe.setLocationHref wrapper. - * +require {goog.dom.safe} - * @param {?Window} win The window object. - * @param {?} url The url. - */ -function before_setWindowLocationUntyped(win, url) { - win.location = url; -} - -/** - * @param {?Window} win The window object. - * @param {?} url The url. - */ -function after_setWindowLocationUntyped(win, url) { - goog.dom.safe.setLocationHref(win.location, goog.asserts.assertString(url)); -} diff --git a/src/com/google/javascript/refactoring/examples/refasterjs/security/window_open.js b/src/com/google/javascript/refactoring/examples/refasterjs/security/window_open.js deleted file mode 100644 index 22c7d66f099..00000000000 --- a/src/com/google/javascript/refactoring/examples/refasterjs/security/window_open.js +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright 2014 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. - */ - -/** - * @fileoverview RefasterJS templates for replacing calls to Window#open - * with calls to the goog.dom.safe.openInWindow wrapper. - * - * For benign URLs, openInWindow simply calls the underlying API. - * For malicious URLs (such as 'javascript:evil()') however, - * the URL is sanitized and replaced with an innocuous value. - * - * As such, using the safe wrapper prevents XSS vulnerabilities that would - * otherwise be present if the URL is derived from untrusted input. - * - * openInWindow requires a compile-time constant window name. Calls which have a - * variable window name are treated separately. - */ - -goog.require('goog.dom.safe'); -goog.require('goog.string.Const'); - -/** - * goog.dom.safe.openInWindow uses the global window instance by - * default. Therefore, we can to Window#open on the - * global window constant with a more readable alternative - -/** - * @param {?Window|undefined} win - * @param {string} string_literal_url - */ -function do_not_change_stringLiteral(win, string_literal_url) { - win.open(string_literal_url); -} - -/** - * @param {?Window|undefined} win - * @param {string} string_literal_url - * @param {string} name - */ -function do_not_change_stringLiteralName(win, string_literal_url, name) { - win.open(string_literal_url, name); -} - -/** - * @param {?Window|undefined} win - * @param {string} string_literal_url - * @param {string} name - * @param {string} spec - */ -function do_not_change_stringLiteralSpec(win, string_literal_url, name, spec) { - win.open(string_literal_url, name, spec); -} - -/** - * +require {goog.dom.safe} - * @param {string} url - */ -function before_windowGlobalOpen(url) { - window.open(url); -} - -/** - * @param {string} url - */ -function after_windowGlobalOpen(url) { - goog.dom.safe.openInWindow(url); -} - - -/** - * +require {goog.dom.safe} - * @param {?Window|undefined} win - * @param {string} url - */ -function before_windowOpen(win, url) { - win.open(url); -} - -/** - * @param {?Window|undefined} win - * @param {string} url - */ -function after_windowOpen(win, url) { - goog.dom.safe.openInWindow(url, win); -} - -/** - * Name must be a string literal. - */ -/** - * +require {goog.dom.safe} - * +require {goog.string.Const} - * @param {?Window|undefined} win - * @param {string} url - * @param {string} string_literal_name - */ -function before_windowOpenName(win, url, string_literal_name) { - win.open(url, string_literal_name); -} - -/** - * @param {?Window|undefined} win - * @param {string} url - * @param {string} string_literal_name - */ -function after_windowOpenName(win, url, string_literal_name) { - goog.dom.safe.openInWindow( - url, win, goog.string.Const.from(string_literal_name)); -} - -/** - * +require {goog.dom.safe} - * +require {goog.string.Const} - * @param {?Window|undefined} win - * @param {string} url - * @param {string} string_literal_name - * @param {string} spec - */ -function before_windowOpenNameSpec(win, url, string_literal_name, spec) { - win.open(url, string_literal_name, spec); -} - -/** - * @param {?Window|undefined} win - * @param {string} url - * @param {string} string_literal_name - * @param {string} spec - */ -function after_windowOpenNameSpec(win, url, string_literal_name, spec) { - goog.dom.safe.openInWindow( - url, win, goog.string.Const.from(string_literal_name), spec); -} diff --git a/src/com/google/javascript/refactoring/examples/refasterjs/security/window_open_nonconst_name.js b/src/com/google/javascript/refactoring/examples/refasterjs/security/window_open_nonconst_name.js deleted file mode 100644 index f14a93b4e4f..00000000000 --- a/src/com/google/javascript/refactoring/examples/refasterjs/security/window_open_nonconst_name.js +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2017 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. - */ - -/** - * @fileoverview RefasterJS templates for replacing calls to - * Window#open that have a non-constant window name with invalid calls - * to the goog.dom.safe.openInWindow wrapper. - * - * The safe wrapper only allows compile-time constant values, so we - * handle these separately. - */ - -goog.require('goog.dom.safe'); -goog.require('goog.string.Const'); - -/** - * @param {?Window|undefined} win - * @param {string} string_literal_url - */ -function do_not_change_stringLiteral(win, string_literal_url) { - win.open(string_literal_url); -} - -/** - * @param {?Window|undefined} win - * @param {string} string_literal_url - * @param {string} name - */ -function do_not_change_stringLiteralName(win, string_literal_url, name) { - win.open(string_literal_url, name); -} - -/** - * @param {?Window|undefined} win - * @param {string} string_literal_url - * @param {string} name - * @param {string} spec - */ -function do_not_change_stringLiteralSpec(win, string_literal_url, name, spec) { - win.open(string_literal_url, name, spec); -} - -/** - * @param {?Window|undefined} win - * @param {string} url - * @param {string} string_literal_name - */ -function do_not_change_windowOpenStringLiteralName( - win, url, string_literal_name) { - win.open(url, string_literal_name); -} - -/** - * @param {?Window|undefined} win - * @param {string} url - * @param {string} string_literal_name - * @param {string} spec - */ -function do_not_change_windowOpenStringLiteralNameSpec( - win, url, string_literal_name, spec) { - win.open(url, string_literal_name, spec); -} - -/** - * +require {goog.dom.safe} - * +require {goog.string.Const} - * @param {?Window|undefined} win - * @param {string} url - * @param {string} name - */ -function before_windowOpenVariableName(win, url, name) { - win.open(url, name); -} - -/** - * @param {?Window|undefined} win - * @param {string} url - * @param {string} name - */ -function after_windowOpenVariableName(win, url, name) { - goog.dom.safe.openInWindow(url, win, goog.string.Const.from('FIXME' + name)); -} - -/** - * +require {goog.dom.safe} - * +require {goog.string.Const} - * @param {?Window|undefined} win - * @param {string} url - * @param {string} name - * @param {string} spec - */ -function before_windowOpenVariableNameSpec(win, url, name, spec) { - win.open(url, name, spec); -} - -/** - * @param {?Window|undefined} win - * @param {string} url - * @param {string} name - * @param {string} spec - */ -function after_windowOpenVariableNameSpec(win, url, name, spec) { - goog.dom.safe.openInWindow( - url, win, goog.string.Const.from('FIXME' + name), spec); -} diff --git a/src/com/google/javascript/refactoring/examples/refasterjs/string_indexof_to_includes.js b/src/com/google/javascript/refactoring/examples/refasterjs/string_indexof_to_includes.js deleted file mode 100644 index fd9e0f1409f..00000000000 --- a/src/com/google/javascript/refactoring/examples/refasterjs/string_indexof_to_includes.js +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright 2017 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. - */ - -/** - * @fileoverview RefasterJS templates for replacing the usage of - * String.prototype.indexOf to determine whether one string may be found within - * another string or not with String.prototype.includes. - * - * Note that String.prototype.includes is case sensitive. - * - * Available in: - * - Chrome 41+ - * - Firefox 40+ - * - Edge (Yes) - * - Opera n/a - * - Safari 9+ - * - IE n/a - * - * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes - * - * This refactoring covers the most common cases in which this can be expressed: - * - * 'str.includes(subStr)' is equivalent to: - * - str.indexOf(subStr) != -1 - * - str.indexOf(subStr) !== -1 - * - str.indexOf(subStr) > -1 - * - str.indexOf(subStr) >= 0 - * - * '!str.includes(subStr)' is equivalent to: - * - str.indexOf(subStr) == -1 - * - str.indexOf(subStr) === -1 - * - str.indexOf(subStr) < 0 - */ - -// subStr found in the string. - -/** - * @param {string} str - * @param {string} subStr - * @suppress {uselessCode} - */ -function before_indexOfNotEqualsMinusOne(str, subStr) { - str.indexOf(subStr) != -1; -} - -/** - * @param {string} str - * @param {string} subStr - */ -function after_indexOfNotEqualsMinusOne(str, subStr) { - str.includes(subStr); -} - -/** - * @param {string} str - * @param {string} subStr - * @suppress {uselessCode} - */ -function before_indexOfStronglyNotEqualsMinusOne(str, subStr) { - str.indexOf(subStr) !== -1; -} - -/** - * @param {string} str - * @param {string} subStr - */ -function after_indexOfStronglyNotEqualsMinusOne(str, subStr) { - str.includes(subStr); -} - -/** - * @param {string} str - * @param {string} subStr - * @suppress {uselessCode} - */ -function before_indexOfGreaterThanMinusOne(str, subStr) { - str.indexOf(subStr) > -1; -} - -/** - * @param {string} str - * @param {string} subStr - */ -function after_indexOfGreaterThanMinusOne(str, subStr) { - str.includes(subStr); -} - -/** - * @param {string} str - * @param {string} subStr - * @suppress {uselessCode} - */ -function before_indexOfGreaterThanOrEqualsZero(str, subStr) { - str.indexOf(subStr) >= 0; -} - -/** - * @param {string} str - * @param {string} subStr - */ -function after_indexOfGreaterThanOrEqualsZero(str, subStr) { - str.includes(subStr); -} - -// subStr NOT found in the string. - -/** - * @param {string} str - * @param {string} subStr - * @suppress {uselessCode} - */ -function before_indexOfEqualsMinusOne(str, subStr) { - str.indexOf(subStr) == -1; -} - -/** - * @param {string} str - * @param {string} subStr - * @suppress {uselessCode} - */ -function after_indexOfEqualsMinusOne(str, subStr) { - !str.includes(subStr); -} - -/** - * @param {string} str - * @param {string} subStr - * @suppress {uselessCode} - */ -function before_indexOfStronglyEqualsMinusOne(str, subStr) { - str.indexOf(subStr) === -1; -} - -/** - * @param {string} str - * @param {string} subStr - * @suppress {uselessCode} - */ -function after_indexOfStronglyEqualsMinusOne(str, subStr) { - !str.includes(subStr); -} - -/** - * @param {string} str - * @param {string} subStr - * @suppress {uselessCode} - */ -function before_indexOfLessThanZero(str, subStr) { - str.indexOf(subStr) < 0; -} - -/** - * @param {string} str - * @param {string} subStr - * @suppress {uselessCode} - */ -function after_indexOfLessThanZero(str, subStr) { - !str.includes(subStr); -} - -/** - * @param {string} str - * @param {string} subStr - * @suppress {uselessCode} - */ -function before_bitwiseNot(str, subStr) { - ~str.indexOf(subStr); -} - -/** - * @param {string} str - * @param {string} subStr - * @suppress {uselessCode} - */ -function after_bitwiseNot(str, subStr) { - str.includes(subStr); -} diff --git a/src/com/google/javascript/refactoring/testing/RefasterJsTestCase.java b/src/com/google/javascript/refactoring/testing/RefasterJsTestCase.java deleted file mode 100644 index b07b3743d39..00000000000 --- a/src/com/google/javascript/refactoring/testing/RefasterJsTestCase.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright 2016 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.refactoring.testing; - -import static com.google.common.collect.ImmutableList.toImmutableList; -import static com.google.common.truth.Truth.assertThat; -import static java.nio.charset.StandardCharsets.UTF_8; - -import com.google.auto.value.AutoValue; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import com.google.common.io.Files; -import com.google.common.truth.Correspondence; -import com.google.javascript.jscomp.CommandLineRunner; -import com.google.javascript.jscomp.CompilerOptions; -import com.google.javascript.refactoring.ApplySuggestedFixes; -import com.google.javascript.refactoring.RefactoringDriver; -import com.google.javascript.refactoring.RefasterJsScanner; -import com.google.javascript.refactoring.SuggestedFix; -import java.io.File; -import java.io.IOException; -import java.util.List; - -/** RefasterJsTestCase */ -@AutoValue -public abstract class RefasterJsTestCase { - - public static Builder builder() { - return new AutoValue_RefasterJsTestCase.Builder(); - } - - /** Path of the JAR resource containing the RefasterJs template to apply. */ - public abstract String getTemplatePath(); - - /** Path of the external file containing the input JS. */ - public abstract String getInputPath(); - - /** Paths of the external files containing the expected output JS. */ - public abstract ImmutableSet getExpectedOutputPaths(); - - /** Paths of the external files containing other JS to include. */ - public abstract ImmutableSet getAdditionalSourcePaths(); - - /** Builder */ - @AutoValue.Builder - public abstract static class Builder { - - public abstract Builder setTemplatePath(String x); - - public abstract Builder setInputPath(String x); - - public final Builder addExpectedOutputPath(String x) { - this.expectedOutputPathsBuilder().add(x); - return this; - } - - public final Builder addAdditionalSourcePath(String x) { - this.additionalSourcePathsBuilder().add(x); - return this; - } - - public final void test() { - try { - this.build().test(); - } catch (IOException e) { - throw new AssertionError(e); - } - } - - abstract ImmutableSet.Builder expectedOutputPathsBuilder(); - - abstract ImmutableSet.Builder additionalSourcePathsBuilder(); - - abstract RefasterJsTestCase build(); - } - - private void test() throws IOException { - // Given - RefasterJsScanner scanner = new RefasterJsScanner(); - scanner.loadRefasterJsTemplate(this.getTemplatePath()); - - ImmutableList expectedOutputs = - this.getExpectedOutputPaths().stream() - .map(RefasterJsTestCase::slurpFile) - .collect(toImmutableList()); - - RefactoringDriver.Builder driverBuilder = - new RefactoringDriver.Builder() - .addExterns(CommandLineRunner.getBuiltinExterns(CompilerOptions.Environment.BROWSER)); - for (String additionalSourcePath : this.getAdditionalSourcePaths()) { - driverBuilder.addInputsFromFile(additionalSourcePath); - } - RefactoringDriver driver = driverBuilder.addInputsFromFile(this.getInputPath()).build(); - - // When - List fixes = driver.drive(scanner); - ImmutableList newCode = - ApplySuggestedFixes.applyAllSuggestedFixChoicesToCode( - fixes, ImmutableMap.of(this.getInputPath(), slurpFile(this.getInputPath()))) - .stream() - .map(m -> m.get(this.getInputPath())) - .collect(toImmutableList()); - - // Then - assertThat(driver.getCompiler().getErrors()).isEmpty(); - assertThat(driver.getCompiler().getWarnings()).isEmpty(); - assertThat(newCode) - .comparingElementsUsing(IGNORING_WHITESPACE_CORRESPONDENCE) - .containsExactlyElementsIn(expectedOutputs); - } - - private static String slurpFile(String originalFile) { - try { - return Files.asCharSource(new File(originalFile), UTF_8).read(); - } catch (IOException e) { - throw new AssertionError(e); - } - } - - private static final Correspondence IGNORING_WHITESPACE_CORRESPONDENCE = - Correspondence.transforming( - RefasterJsTestCase::replaceTrailingWhitespace, - RefasterJsTestCase::replaceTrailingWhitespace, - "equals (except for whitespace)"); - - private static String replaceTrailingWhitespace(String contents) { - return contents.replaceAll("[ \t]*\n", "\n"); - } - - RefasterJsTestCase() { - // Only subclassed by AutoValue. - } -} diff --git a/test/com/google/javascript/refactoring/RefasterJsScannerTest.java b/test/com/google/javascript/refactoring/RefasterJsScannerTest.java deleted file mode 100644 index 630c00203ce..00000000000 --- a/test/com/google/javascript/refactoring/RefasterJsScannerTest.java +++ /dev/null @@ -1,1020 +0,0 @@ -/* - * Copyright 2014 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.refactoring; - -import static com.google.common.truth.Truth.assertThat; -import static com.google.javascript.jscomp.base.JSCompStrings.lines; -import static org.junit.Assert.fail; - -import com.google.common.base.Joiner; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.javascript.jscomp.Compiler; -import com.google.javascript.jscomp.CompilerOptions; -import com.google.javascript.jscomp.SourceFile; -import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.stream.Collectors; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** - * Unit tests for {RefasterJsScanner}. - * - * The RefasterJsScanner must be initialized with the compiler used to compile the - * test code so that the types from the template and the test code match. - * Therefore, it is important to compile the test code first before creating the - * scanner, and to reuse the same compiler object for both the test code and the - * scanner. - * - */ -// TODO(mknichel): Make this a SmallTest by disabling threads in the JS Compiler. -@RunWith(JUnit4.class) -public class RefasterJsScannerTest { - - @BeforeClass - public static void noLogSpam() { - Logger.getLogger("com.google").setLevel(Level.OFF); - } - - @Test - public void testInitialize_missingTemplates() throws Exception { - try { - Compiler compiler = createCompiler(); - compileTestCode(compiler, "", ""); - createScanner(compiler, ""); - fail("An exception should have been thrown for missing templates."); - } catch (IllegalStateException expected) {} - - try { - Compiler compiler = createCompiler(); - compileTestCode(compiler, "", ""); - createScanner(compiler, "function notATemplate() {}"); - fail("An exception should have been thrown for missing templates."); - } catch (IllegalStateException expected) {} - - try { - Compiler compiler = createCompiler(); - compileTestCode(compiler, "", ""); - createScanner(compiler, "function after_foo() {}"); - fail("An exception should have been thrown for missing templates."); - } catch (IllegalStateException expected) {} - } - - @Test - public void testInitialize_missingAfterTemplate() throws Exception { - try { - Compiler compiler = createCompiler(); - compileTestCode(compiler, "", ""); - createScanner(compiler, "function before_foo() {'bar'};"); - fail("An exception should have been thrown for missing the after template."); - } catch (IllegalStateException expected) {} - } - - @Test - public void testInitialize_duplicateTemplateName() throws Exception { - try { - Compiler compiler = createCompiler(); - compileTestCode(compiler, "", ""); - createScanner(compiler, "function before_foo() {}; function before_foo() {};"); - fail("RefasterJS templates are not allowed to have the same name."); - } catch (IllegalStateException expected) {} - } - - @Test - public void testInitialize_emptyBeforeTemplates() throws Exception { - try { - Compiler compiler = createCompiler(); - compileTestCode(compiler, "", ""); - createScanner(compiler, "function before_foo() {}; function after_foo() {};"); - fail("RefasterJS templates are not allowed to be empty!."); - } catch (IllegalStateException expected) {} - } - - @Test - public void testInitialize_success() throws Exception { - Compiler compiler = createCompiler(); - compileTestCode(compiler, "", ""); - createScanner(compiler, "function before_foo() {'str';}; function after_foo() {};"); - } - - @Test - public void test_simple() throws Exception { - String originalCode = "var loc = 'str';"; - String expectedCode = "'bar';"; - String template = "" - + "function before_foo() {\n" - + " var a = 'str';\n" - + "};\n" - + "function after_foo() {\n" - + " 'bar';\n" - + "}\n"; - assertChanges("", originalCode, template, expectedCode); - } - - @Test - public void test_semicolonCorrect() throws Exception { - String externs = "" - + "/** @constructor */\n" - + "function Location() {};\n" - + "/** @type {string} */\n" - + "Location.prototype.href;\n" - + "function foo() {}\n" - + "/** @type {Location} */ var loc;"; - String originalCode = "loc.href = 'str';"; - String expectedCode = "foo();"; - String template = "" - + "/** @param {Location} loc */" - + "function before_foo(loc) {\n" - + " loc.href = 'str';\n" - + "};\n" - + "function after_foo() {\n" - + " foo();\n" - + "}\n"; - assertChanges(externs, originalCode, template, expectedCode); - } - - @Test - public void test_operatorPrecedence() throws Exception { - String originalCode = "f(1 || 2) && f(3) && f(4) == 5 && 6 == f(7) && 8 + f(9);"; - String expectedCode = - "(1 || 2) == 0 && 3 == 0 && (4 == 0) == 5 && 6 == (7 == 0) && 8 + (9 == 0);"; - String template = - lines( - "/** @param {?} x */", - "function before_foo(x) {", - " f(x);", - "};", - "/** @param {?} x */", - "function after_foo(x) {", - " x == 0;", - "}"); - assertChanges("", originalCode, template, expectedCode); - } - - @Test - public void test_withTypes() throws Exception { - String externs = "" - + "/** @constructor */\n" - + "function FooType() {}\n" - + "FooType.prototype.bar = function() {};\n" - + "/** @type {FooType} */ var obj;"; - String originalCode = "obj.bar();"; - String expectedCode = "obj.baz();"; - String template = "" - + "/**\n" - + " * @param {FooType} foo\n" - + " */\n" - + "function before_foo(foo) {\n" - + " foo.bar();\n" - + "};\n" - + "/**\n" - + " * @param {FooType} foo\n" - + " */\n" - + "function after_foo(foo) {\n" - + " foo.baz();\n" - + "}\n"; - assertChanges(externs, originalCode, template, expectedCode); - } - - @Test - public void test_multiLines() throws Exception { - String externs = "" - + "/** @constructor */\n" - + "function FooType() {}\n" - + "FooType.prototype.bar = function() {};\n" - + "FooType.prototype.baz = function() {};"; - String preamble = "var obj = new FooType();\n"; - String postamble = "var someOtherCode = 3;\n"; - String originalCode = "" - + preamble - + "obj.bar();\n" - + "obj.baz();\n" - + postamble; - String expectedCode = preamble + postamble; - String template = "" - + "/**\n" - + " * @param {FooType} foo\n" - + " */\n" - + "function before_foo(foo) {\n" - + " foo.bar();\n" - + " foo.baz();\n" - + "};\n" - + "/**\n" - + " * @param {FooType} foo\n" - + " */\n" - + "function after_foo(foo) {\n" - + "}\n"; - assertChanges(externs, originalCode, template, expectedCode); - } - - @Test - public void test_replaceFunctionArgument() throws Exception { - String externs = "" - + "/** @constructor */\n" - + "function MyClass() {};\n" - + "MyClass.prototype.foo = function() {};\n" - + "MyClass.prototype.bar = function() {};\n" - + "/** @type {MyClass} */ var clazz;"; - String originalCode = "alert(clazz.foo());"; - String expectedCode = "alert(clazz.bar());"; - String template = "" - + "/** @param {MyClass} clazz */" - + "function before_foo(clazz) {\n" - + " clazz.foo();\n" - + "};\n" - + "/** @param {MyClass} clazz */" - + "function after_foo(clazz) {\n" - + " clazz.bar();\n" - + "}\n"; - assertChanges(externs, originalCode, template, expectedCode); - } - - @Test - public void test_replaceLeftHandSideOfAssignment() throws Exception { - String externs = "" - + "/** @constructor */\n" - + "function MyClass() {};\n"; - String originalCode = "MyClass.prototype.foo = function() {};\n"; - String expectedCode = "MyClass.prototype.bar = function() {};\n"; - String template = "" - + "function before_foo() {\n" - + " MyClass.prototype.foo\n" - + "};\n" - + "function after_foo() {\n" - + " MyClass.prototype.bar\n" - + "}\n"; - assertChanges(externs, originalCode, template, expectedCode); - } - - @Test - public void test_replaceRightHandSideOfAssignment() throws Exception { - String externs = "" - + "/** @constructor */\n" - + "function MyClass() {};\n" - + "MyClass.prototype.foo = function() {};\n" - + "MyClass.prototype.bar = function() {};\n"; - String originalCode = "var x = MyClass.prototype.foo;"; - String expectedCode = "var x = MyClass.prototype.bar;"; - String template = "" - + "function before_foo() {\n" - + " MyClass.prototype.foo\n" - + "};\n" - + "function after_foo() {\n" - + " MyClass.prototype.bar\n" - + "}\n"; - assertChanges(externs, originalCode, template, expectedCode); - } - - @Test - public void test_doesNotAddSpuriousNewline() throws Exception { - String externs = "" - + "/** @constructor */\n" - + "function MyClass() {};\n" - + "MyClass.prototype.foo = function() {};\n" - + "MyClass.prototype.bar = function() {};\n" - + "/** @type {MyClass} */ var clazz;\n"; - String originalCode = "clazz.foo();"; - String expectedCode = "clazz.bar();"; - String template = "" - + "/** @param {MyClass} clazz */" - + "function before_foo(clazz) {\n" - + " clazz.foo();\n" - + "};\n" - + "/** @param {MyClass} clazz */" - + "function after_foo(clazz) {\n" - + " clazz.bar();\n" - + "}\n"; - assertChanges(externs, originalCode, template, expectedCode); - } - - @Test - public void test_throwStatements() throws Exception { - String externs = ""; - String originalCode = "throw Error('foo');"; - String expectedCode = "throw getError();"; - String template = "" - + "/** @param {string} msg */\n" - + "function before_template(msg) {\n" - + " throw Error(msg);\n" - + "}\n" - + "/** @param {string} msg */\n" - + "function after_template(msg) {\n" - + " throw getError();\n" - + "}\n"; - assertChanges(externs, originalCode, template, expectedCode); - - originalCode = "function f() {throw Error('foo');}"; - expectedCode = "function f() {throw getError();}"; - assertChanges(externs, originalCode, template, expectedCode); - - originalCode = "" - + "if (true) {\n" - + " throw Error('foo');\n" - + "}"; - expectedCode = "" - + "if (true) {\n" - + " throw getError();\n" - + "}"; - assertChanges(externs, originalCode, template, expectedCode); -} - - @Test - public void test_whileStatements() throws Exception { - String externs = "/** @return {string} */ function getFoo() {return 'foo';}"; - String originalCode = "while(getFoo()) {}"; - String expectedCode = "while(getBar()) {}"; - String template = "" - + "function before_template() {\n" - + " getFoo();\n" - + "}\n" - + "function after_template() {\n" - + " getBar();\n" - + "}\n"; - assertChanges(externs, originalCode, template, expectedCode); - } - - @Test - public void test_doWhileStatements() throws Exception { - String externs = "/** @return {string} */ function getFoo() {return 'foo';}"; - String originalCode = "do {} while(getFoo());"; - String expectedCode = "do {} while(getBar());"; - String template = "" - + "function before_template() {\n" - + " getFoo();\n" - + "}\n" - + "function after_template() {\n" - + " getBar();\n" - + "}\n"; - assertChanges(externs, originalCode, template, expectedCode); - } - - @Test - public void test_returnStatement() throws Exception { - String externs = "/** @return {string} */ function getFoo() {return 'foo';}"; - String originalCode = "function f() { return getFoo(); }"; - String expectedCode = "function f() { return getBar(); }"; - String template = "" - + "function before_template() {\n" - + " getFoo();\n" - + "}\n" - + "function after_template() {\n" - + " getBar();\n" - + "}\n"; - assertChanges(externs, originalCode, template, expectedCode); - - originalCode = "function f() { return getFoo() == 'foo'; }"; - expectedCode = "function f() { return getBar() == 'foo'; }"; - assertChanges(externs, originalCode, template, expectedCode); - } - - @Test - public void test_switchStatement() throws Exception { - String externs = "/** @return {string} */ function getFoo() {return 'foo';}"; - String originalCode = "" - + "switch(getFoo()) {\n" - + " default:\n" - + " break;\n" - + "}"; - String expectedCode = "" - + "switch(getBar()) {\n" - + " default:\n" - + " break;\n" - + "}"; - String template = "" - + "function before_template() {\n" - + " getFoo();\n" - + "}\n" - + "function after_template() {\n" - + " getBar();\n" - + "}\n"; - assertChanges(externs, originalCode, template, expectedCode); - } - - @Test - public void test_caseStatement() throws Exception { - String externs = "" - + "var str = 'foo';\n" - + "var CONSTANT = 'bar';\n"; - String originalCode = "" - + "switch(str) {\n" - + " case CONSTANT:\n" - + " break;\n" - + "}"; - String expectedCode = "" - + "switch(str) {\n" - + " case getValue():\n" - + " break;\n" - + "}"; - String template = "" - + "function before_template() {\n" - + " CONSTANT\n" - + "}\n" - + "function after_template() {\n" - + " getValue()\n" - + "}\n"; - assertChanges(externs, originalCode, template, expectedCode); - } - - @Test - public void test_forStatement() throws Exception { - String externs = "" - + "var obj = {};\n" - + "obj.prop = 6;" - + "var CONSTANT = 3;\n"; - String originalCode = "for (var i = CONSTANT; i < 5; i++) {}"; - String expectedCode = "for (var i = CONSTANT2; i < 5; i++) {}"; - String template = "" - + "function before_template() {\n" - + " CONSTANT\n" - + "}\n" - + "function after_template() {\n" - + " CONSTANT2\n" - + "}\n"; - assertChanges(externs, originalCode, template, expectedCode); - - originalCode = "for (var i = 0; i < CONSTANT; i++) {}"; - expectedCode = "for (var i = 0; i < CONSTANT2; i++) {}"; - assertChanges(externs, originalCode, template, expectedCode); - - originalCode = "for (var i = 0; i < CONSTANT; i++) {}"; - expectedCode = "for (var i = 0; i < obj.prop; i++) {}"; - template = "" - + "function before_template() {\n" - + " CONSTANT\n" - + "}\n" - + "function after_template() {\n" - + " obj.prop\n" - + "}\n"; - assertChanges(externs, originalCode, template, expectedCode); - - originalCode = "for (var prop in obj) {}"; - expectedCode = "for (var prop in getObj()) {}"; - template = "" - + "function before_template() {\n" - + " obj\n" - + "}\n" - + "function after_template() {\n" - + " getObj()\n" - + "}\n"; - assertChanges(externs, originalCode, template, expectedCode); - } - - @Test - public void test_comparisons() throws Exception { - String externs = "" - + "var obj = {};\n" - + "obj.prop = 5;"; - String originalCode = "if (obj.prop == 5) {}"; - String expectedCode = "if (3 == 5) {}"; - String template = "" - + "function before_template() {\n" - + " obj.prop;\n" - + "}\n" - + "function after_template() {\n" - + " 3;\n" - + "}\n"; - assertChanges(externs, originalCode, template, expectedCode); - } - - @Test - public void test_arrayAccess() throws Exception { - String externs = "" - + "var arr = [];\n" - + "var i = 0;\n" - + "/** @return {number} */ function getNewIndex() {}"; - String originalCode = "arr[i];"; - String expectedCode = "arr[getNewIndex()];"; - String template = "" - + "function before_template() {\n" - + " i;\n" - + "}\n" - + "function after_template() {\n" - + " getNewIndex();\n" - + "}\n"; - assertChanges(externs, originalCode, template, expectedCode); - } - - @Test - public void test_functionCalls() throws Exception { - // Assigning the function as a property of an object is important to this test since it - // tracks a corner case in the TemplateAstMatcher code. - String externs = "var foo = {}; /** @return {number} */ foo.someFn = function() {}"; - String originalCode = "foo.someFn();"; - String expectedCode = "foo.someFn().someOtherFn();"; - String template = "" - + "/** @param {function():number} fn */\n" - + "function before_template(fn) {\n" - + " fn();\n" - + "}\n" - + "/** @param {function():number} fn */\n" - + "function after_template(fn) {\n" - + " fn().someOtherFn();\n" - + "}\n"; - assertChanges(externs, originalCode, template, expectedCode); - } - - @Test - public void test_strictSubtypeMatching() throws Exception { - String externs = "" - + "/** @constructor */\n" - + "function T() {};\n" - + "/** @type {string} */\n" - + "T.prototype.p;\n" - + "/** @constructor @extends {T} */\n" - + "function S() {};\n" - + "/** @param {!T} someT */\n" - + "function setP(someT) {};\n"; - String template = "" - + "/** @param {!T} t */\n" - + "function before_template(t) {\n" - + " t.p = 'foo';\n" - + "}\n" - + "/** @param {!T} t */\n" - + "function after_template(t) {\n" - + " setP(t);\n" - + "}\n"; - String originalCode = "theT.p = 'foo';"; - String expectedCode = "setP(theT);"; - - // {!T} matches {!T} - assertChanges(externs + "/** @type {!T} */ var theT;", originalCode, template, expectedCode); - - // {?T} in the code does not match {!T} in the template. - assertChanges( - externs + "/** @type {?T} */ var theT;", - originalCode, - template, - (String) null); // No changes. - - // {unknown} does not match {!T} - assertChanges(externs + "var theT;", originalCode, template, (String) null); // No changes. - - // {!S} matches {!T} - assertChanges(externs + "/** @type {!S} */ var theT;", originalCode, template, expectedCode); - - // {?S} does not match {!T} - assertChanges( - externs + "/** @type {?S} */ var theT;", - originalCode, - template, - (String) null); // No changes. - } - - @Test - public void test_templatesEvaluatedInOrder() throws Exception { - String externs = "" - + "/** @constructor */\n" - + "function T() {};\n" - + "/** @type {string} */\n" - + "T.prototype.p;\n" - + "/** @constructor @extends {T} */\n" - + "function S() {};\n" - + "/** @param {!T} someT */\n" - + "function setP(someT) {};\n" - + "/** @param {!S} someS */\n" - + "function setPonS(someS) {};\n" - + "/** @type {!T} */ var theT;" - + "/** @type {!S} */ var theS;"; - String template = "" - + "/** @param {!S} s */\n" - + "function before_template_S(s) {\n" - + " s.p = 'foo';\n" - + "}\n" - + "/** @param {!S} s */\n" - + "function after_template_S(t) {\n" - + " setPonS(s);\n" - + "}\n" - + "\n" - + "/** @param {!T} t */\n" - + "function before_template_T(t) {\n" - + " t.p = 'foo';\n" - + "}\n" - + "/** @param {!T} t */\n" - + "function after_template_T(t) {\n" - + " setP(t);\n" - + "}\n"; - String originalCode = "theT.p = 'foo'; theS.p = 'foo';"; - // Templates are evaluated in order: - // - theT.p does not match before_template_S but matches before_template_T - // - theS.p would match either template (see {@link #test_strictSubtypeMatching}), - // but since before_template_S comes first it takes precedence. - String expectedCode = "setP(theT); setPonS(theS);"; - assertChanges(externs, originalCode, template, expectedCode); - } - - @Test - public void test_es6() throws Exception { - String externs = "" - + "/** @constructor */\n" - + "function FooType() {}\n" - + "/** @param {string} str */" - + "FooType.prototype.bar = function(str) {};\n" - + "/** @param {string} str */" - + "FooType.prototype.baz = function(str) {};\n"; - String template = "" - + "/**\n" - + " * @param {FooType} foo\n" - + " * @param {string} str\n" - + " */\n" - + "function before_foo(foo, str) {\n" - + " foo.bar(str);\n" - + "};\n" - + "/**\n" - + " * @param {FooType} foo\n" - + " * @param {string} str\n" - + " */\n" - + "function after_foo(foo, str) {\n" - + " foo.baz(str);\n" - + "}\n"; - String originalCode = "" - + "goog.module('foo.bar');\n" - + "const STR = '3';\n" - + "const Clazz = class {\n" - + " constructor() { /** @const */ this.obj = new FooType(); }\n" - + " someMethod() { this.obj.bar(STR); }\n" - + "};\n" - + "exports.Clazz = Clazz;\n"; - String expectedCode = "" - + "goog.module('foo.bar');\n" - + "const STR = '3';\n" - + "const Clazz = class {\n" - + " constructor() { /** @const */ this.obj = new FooType(); }\n" - + " someMethod() { this.obj.baz(STR); }\n" - + "};\n" - + "exports.Clazz = Clazz;\n"; - assertChanges(externs, originalCode, template, expectedCode); - } - - @Test - public void test_unknownTemplateTypes() throws Exception { - // By declaring a new type in the template code that does not appear in the original code, - // the result of this refactoring should be a no-op. However, if template type matching isn't - // correct, the template type could be treated as an unknown type which would incorrectly - // match the original code. This test ensures this behavior is right. - String externs = ""; - String originalCode = "" - + "/** @constructor */\n" - + "function Clazz() {};\n" - + "var cls = new Clazz();\n" - + "cls.showError('boo');\n"; - String template = "" - + "/** @constructor */\n" - + "function SomeClassNotInCompilationUnit() {};\n" - + "var foo = new SomeClassNotInCompilationUnit();\n" - + "foo.showError('bar');\n" - + "\n" - + "/**" - + " * @param {SomeClassNotInCompilationUnit} obj\n" - + " * @param {string} msg\n" - + " */\n" - + "function before_template(obj, msg) {\n" - + " obj.showError(msg);\n" - + "}\n" - + "/**" - + " * @param {SomeClassNotInCompilationUnit} obj\n" - + " * @param {string} msg\n" - + " */\n" - + "function after_template(obj, msg) {\n" - + " obj.showError(msg, false);\n" - + "}\n"; - assertChanges(externs, originalCode, template, (String) null); - } - - @Test - public void test_unknownTemplateTypesNonNullable() throws Exception { - // By declaring a new type in the template code that does not appear in the original code, - // the result of this refactoring should be a no-op. However, if template type matching isn't - // correct, the template type could be treated as an unknown type which would incorrectly - // match the original code. This test ensures this behavior is right. - String externs = ""; - String originalCode = "" - + "/** @constructor */\n" - + "function Clazz() {};\n" - + "var cls = new Clazz();\n" - + "cls.showError('boo');\n"; - String template = "" - + "/** @constructor */\n" - + "function SomeClassNotInCompilationUnit() {};\n" - + "var foo = new SomeClassNotInCompilationUnit();\n" - + "foo.showError('bar');\n" - + "\n" - + "/**" - + " * @param {!SomeClassNotInCompilationUnit} obj\n" - + " * @param {string} msg\n" - + " */\n" - + "function before_template(obj, msg) {\n" - + " obj.showError(msg);\n" - + "}\n" - + "/**" - + " * @param {!SomeClassNotInCompilationUnit} obj\n" - + " * @param {string} msg\n" - + " */\n" - + "function after_template(obj, msg) {\n" - + " obj.showError(msg, false);\n" - + "}\n"; - assertChanges(externs, originalCode, template, (String) null); - } - - @Test - public void test_importConstGoogRequire() throws Exception { - String externs = ""; - String originalCode = - Joiner.on('\n').join("goog.module('testcase');", "", "function f() { var loc = 'str'; }"); - String expectedCode = - Joiner.on('\n').join( - "goog.module('testcase');", - "const foo = goog.require('goog.foo');", - "", - "function f() { var loc = foo.f(); }"); - String template = - Joiner.on('\n').join( - "/**", - "* +require {goog.foo}", - "*/", - "function before_foo() {", - " var a = 'str';", - "};", - "function after_foo() {", - " var a = goog.foo.f();", - "}"); - assertChanges(externs, originalCode, template, expectedCode); - } - - @Test - public void test_importConstGoogRequireMultipleImports() throws Exception { - String externs = ""; - String originalCode = - Joiner.on('\n').join( - "goog.module('testcase');", - "const alpha = goog.require('goog.alpha');", - "const omega = goog.require('goog.omega');", - "", - "function f() { var loc = 'str'; }"); - String expectedCode = - Joiner.on('\n').join( - "goog.module('testcase');", - "const alpha = goog.require('goog.alpha');", - "const foo = goog.require('goog.foo');", - "const omega = goog.require('goog.omega');", - "", - "function f() { var loc = foo.f(); }"); - String template = - Joiner.on('\n').join( - "/**", - "* +require {goog.foo}", - "*/", - "function before_foo() {", - " var a = 'str';", - "};", - "function after_foo() {", - " var a = goog.foo.f();", - "}"); - assertChanges(externs, originalCode, template, expectedCode); - } - - @Test - public void test_importDestructureConstGoogRequire() throws Exception { - // TODO(b/139953612): Respect existing destructured goog.requires - String externs = ""; - String originalCode = - Joiner.on('\n') - .join( - "goog.module('testcase');", - "const {bar} = goog.require('goog.foo');", - "", - "function f() { var loc = 'str'; }"); - String expectedCode = - Joiner.on('\n') - .join( - "goog.module('testcase');", - "const foo = goog.require('goog.foo');", - "const {bar} = goog.require('goog.foo');", - "", - "function f() { var loc = foo.f(); }"); - String template = - Joiner.on('\n') - .join( - "/**", - "* +require {goog.foo}", - "*/", - "function before_foo() {", - " var a = 'str';", - "};", - "function after_foo() {", - " var a = goog.foo.f();", - "}"); - assertChanges(externs, originalCode, template, expectedCode); - } - - @Test - public void test_importConstGoogRequireAlreadyNamed() throws Exception { - String externs = ""; - String originalCode = - Joiner.on('\n').join( - "goog.module('testcase');", - "const bar = goog.require('goog.foo');", - "", - "var loc = 'str';"); - String expectedCode = - Joiner.on('\n').join( - "goog.module('testcase');", - "const bar = goog.require('goog.foo');", - "", - "var loc = bar.f();"); - String template = - Joiner.on('\n').join( - "/**", - "* +require {goog.foo}", - "*/", - "function before_foo() {", - " var a = 'str';", - "};", - "function after_foo() {", - " var a = goog.foo.f();", - "}"); - assertChanges(externs, originalCode, template, expectedCode); - } - - @Test - public void test_multipleChoices() throws Exception { - String externs = ""; - - String originalCode = Joiner.on('\n').join("goog.module('testcase');", "", "var loc = 'str';"); - String expectedCode1 = - Joiner.on('\n').join("goog.module('testcase');", "", "var loc = 'foo' + 'str';"); - String expectedCode2 = - Joiner.on('\n').join("goog.module('testcase');", "", "var loc = 'bar' + 'str';"); - String template = - Joiner.on('\n') - .join( - "/**", - "* @param {string} str", - "*/", - "function before_foo(str) {", - " var a = str;", - "};", - "/**", - " * @param {string} str", - "*/", - "function after_option_1_foo(str) {", - " var a = 'foo' + str", - "}", - "/**", - " * @param {string} str", - "*/", - "function after_option_2_foo(str) {", - " var a = 'bar' + str", - "}"); - assertChanges(externs, originalCode, template, expectedCode1, expectedCode2); - } - - @Test - public void test_multipleChoicesDifferentImports() throws Exception { - String externs = ""; - - String originalCode = Joiner.on('\n').join("goog.module('testcase');", "", "var loc = 'str';"); - String expectedCode1 = - Joiner.on('\n') - .join( - "goog.module('testcase');", - "const bar = goog.require('goog.bar');", - "const foo = goog.require('goog.foo');", - "", - "var loc = foo.f(bar.b('option1'));"); - String expectedCode2 = - Joiner.on('\n') - .join( - "goog.module('testcase');", - "const baz = goog.require('goog.baz');", - "const foo = goog.require('goog.foo');", - "", - "var loc = foo.f(baz.f('option2'));"); - String template = - Joiner.on('\n') - .join( - "/**", - "* +require {goog.foo}", - "*/", - "function before_foo() {", - " var a = 'str';", - "};", - "/**", - "* +require {goog.foo}", // Duplicates should be ok - "* +require {goog.bar}", - "*/", - "function after_option_1_foo() {", - " var a = goog.foo.f(goog.bar.b('option1'))", - "}", - "/**", - "* +require {goog.baz}", - "*/", - "function after_option_2_foo() {", - " var a = goog.foo.f(goog.baz.f('option2'))", - "}"); - assertChanges(externs, originalCode, template, expectedCode1, expectedCode2); - } - - @Test - public void test_withGetCssName() throws Exception { - String externs = ""; - - String originalCode = Joiner.on('\n').join( - "goog.module('testcase');", - "", - "document.getElementById('foo').class = goog.getCssName('str');"); - String expectedCode = - Joiner.on('\n').join( - "goog.module('testcase');", - "", - "document.getElementById('foo').class = 'foo' + goog.getCssName('str');"); - String template = - Joiner.on('\n') - .join( - "/**", - "* @param {?} obj", - "* @param {?} value", - "*/", - "function before_foo(obj, value) {", - " obj.class = value;", - "};", - "/**", - " * @param {?} obj", - " * @param {?} value", - "*/", - "function after_foo(obj, value) {", - " obj.class = 'foo' + value;", - "}"); - assertChanges(externs, originalCode, template, expectedCode); - } - - private static Compiler createCompiler() { - return new Compiler(); - } - - private static RefasterJsScanner createScanner(Compiler compiler, String template) - throws Exception { - RefasterJsScanner scanner = new RefasterJsScanner(); - scanner.loadRefasterJsTemplateFromCode(template); - scanner.initialize(compiler); - return scanner; - } - - private static void compileTestCode(Compiler compiler, String testCode, String externs) { - CompilerOptions options = RefactoringDriver.getCompilerOptions(); - compiler.compile( - ImmutableList.of(SourceFile.fromCode("externs", "function Symbol() {};" + externs)), - ImmutableList.of(SourceFile.fromCode("test", testCode)), - options); - } - - private static void assertChanges( - String externs, String originalCode, String refasterJsTemplate, String... expectedChoices) - throws Exception { - RefasterJsScanner scanner = new RefasterJsScanner(); - scanner.loadRefasterJsTemplateFromCode(refasterJsTemplate); - - RefactoringDriver driver = - new RefactoringDriver.Builder() - .addExternsFromCode("function Symbol() {};" + externs) - .addInputsFromCode(originalCode) - .addInputsFromCode( - Joiner.on('\n') - .join( - "goog.module('goog.foo');", - "/** Trivial function. \n", - " * @return {string}", - " */", - "exports.f = function () { ", - " return 'str';", - "};"), - "foo.js") - .build(); - List fixes = driver.drive(scanner); - List outputChoices = - ApplySuggestedFixes.applyAllSuggestedFixChoicesToCode( - fixes, ImmutableMap.of("input", originalCode)) - .stream() - .map((m) -> m.get("input")) - .collect(Collectors.toList()); - - assertThat(outputChoices).containsExactlyElementsIn(expectedChoices).inOrder(); - } -} diff --git a/test/com/google/javascript/refactoring/examples/ArrayIndexOfToIncludesTest.java b/test/com/google/javascript/refactoring/examples/ArrayIndexOfToIncludesTest.java deleted file mode 100644 index 6bafab97fee..00000000000 --- a/test/com/google/javascript/refactoring/examples/ArrayIndexOfToIncludesTest.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2017 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.refactoring.examples; - -import com.google.javascript.refactoring.testing.RefasterJsTestCase; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -@RunWith(JUnit4.class) -public class ArrayIndexOfToIncludesTest { - - /** Path of the directory containing test inputs and expected outputs. */ - private static final String TESTDATA_DIR = - "test/" - + "com/google/javascript/refactoring/examples/testdata"; - - /** The RefasterJs template to use. */ - private static final String ARRAY_INDEXOF_TO_INCLUDES_TEMPLATE = - "com/google/javascript/refactoring/examples/refasterjs/array_indexof_to_includes.js"; - - @Test - public void test_refactorings() throws Exception { - RefasterJsTestCase.builder() - .setTemplatePath(ARRAY_INDEXOF_TO_INCLUDES_TEMPLATE) - .setInputPath(TESTDATA_DIR + "/array_indexof_to_includes_in.js") - .addExpectedOutputPath(TESTDATA_DIR + "/array_indexof_to_includes_out.js") - .addAdditionalSourcePath(TESTDATA_DIR + "/goog_base.js") - .test(); - } -} diff --git a/test/com/google/javascript/refactoring/examples/ArrayPrototypeSliceToArrayFromTest.java b/test/com/google/javascript/refactoring/examples/ArrayPrototypeSliceToArrayFromTest.java deleted file mode 100644 index b8e6129c9b3..00000000000 --- a/test/com/google/javascript/refactoring/examples/ArrayPrototypeSliceToArrayFromTest.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2017 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.refactoring.examples; - -import com.google.javascript.refactoring.testing.RefasterJsTestCase; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -@RunWith(JUnit4.class) -public class ArrayPrototypeSliceToArrayFromTest { - - /** Path of the directory containing test inputs and expected outputs. */ - private static final String TESTDATA_DIR = - "test/" - + "com/google/javascript/refactoring/examples/testdata"; - - /** The RefasterJs template to use. */ - private static final String ARRAY_PROTOTYPE_SLICE_TO_ARRAY_FROM_TEMPLATE = - "com/google/javascript/refactoring/examples/refasterjs/array_prototype_slice_to_array_from.js"; - - @Test - public void test_refactorings() throws Exception { - RefasterJsTestCase.builder() - .setTemplatePath(ARRAY_PROTOTYPE_SLICE_TO_ARRAY_FROM_TEMPLATE) - .setInputPath(TESTDATA_DIR + "/array_prototype_slice_to_array_from_in.js") - .addExpectedOutputPath(TESTDATA_DIR + "/array_prototype_slice_to_array_from_out.js") - .addAdditionalSourcePath(TESTDATA_DIR + "/goog_base.js") - .test(); - } -} diff --git a/test/com/google/javascript/refactoring/examples/ChaiExpectToAssertTest.java b/test/com/google/javascript/refactoring/examples/ChaiExpectToAssertTest.java deleted file mode 100644 index 23326ff5aee..00000000000 --- a/test/com/google/javascript/refactoring/examples/ChaiExpectToAssertTest.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2017 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.refactoring.examples; - -import com.google.javascript.refactoring.testing.RefasterJsTestCase; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -@RunWith(JUnit4.class) -public class ChaiExpectToAssertTest { - - /** Path of the directory containing test inputs and expected outputs. */ - private static final String TESTDATA_DIR = - "test/" - + "com/google/javascript/refactoring/examples/testdata"; - - private static final String EXTERNS_DIR = - "" - + "contrib/externs"; - - /** The RefasterJs template to use. */ - private static final String NAVIGATIONAL_XSS_SINKS_TEMPLATE = - "com/google/javascript/refactoring/examples/refasterjs/chai_expect_to_assert.js"; - - @Test - public void test_refactorings() throws Exception { - RefasterJsTestCase.builder() - .setTemplatePath(NAVIGATIONAL_XSS_SINKS_TEMPLATE) - .setInputPath(TESTDATA_DIR + "/chai_expect_to_assert_in.js") - .addExpectedOutputPath(TESTDATA_DIR + "/chai_expect_to_assert_out.js") - .addAdditionalSourcePath(EXTERNS_DIR + "/chai-3.5.js") - .test(); - } -} diff --git a/test/com/google/javascript/refactoring/examples/GoogBindToArrowTest.java b/test/com/google/javascript/refactoring/examples/GoogBindToArrowTest.java deleted file mode 100644 index 343fd3662ab..00000000000 --- a/test/com/google/javascript/refactoring/examples/GoogBindToArrowTest.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright 2017 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.refactoring.examples; - -import com.google.javascript.refactoring.Scanner; -import com.google.javascript.refactoring.testing.RefactoringTestCase; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** Test case for {@link GoogBindToArrow}. */ -@RunWith(JUnit4.class) -public class GoogBindToArrowTest extends RefactoringTestCase { - @Override - protected String getExterns() { - return ""; - } - - @Override - protected Scanner getScanner() { - return new GoogBindToArrow(); - } - - @Test - public void testBasic() { - assertChanges( - LINE_JOINER.join( - "goog.bind(function() {", - " console.log(this.name);", - "}, this)"), - LINE_JOINER.join( - "() => {", - " console.log(this.name);", - "}")); - - assertChanges( - LINE_JOINER.join( - "var f = goog.bind(function() {", - " console.log(this.name);", - "}, this);"), - LINE_JOINER.join( - "var f = () => {", - " console.log(this.name);", - "};")); - } - - @Test - public void testParams() { - assertChanges( - LINE_JOINER.join( - "goog.bind(function(a, b, c) {", - " console.log(this.name);", - "}, this)"), - LINE_JOINER.join( - "(a, b, c) => {", - " console.log(this.name);", - "}")); - } - - @Test - public void testNoThis() { - // TODO(tbreisacher): Since the function doesn't reference `this` at all, we could convert - // to just "function() { console.log('hello'); }" for non-ES6 code, either in this refactoring, - // or possibly as a separate one ("RemoveUnnecessaryGoogBind"). - assertChanges( - LINE_JOINER.join( - "goog.bind(function() {", - " console.log('hello');", - "}, this)"), - LINE_JOINER.join( - "() => {", - " console.log('hello');", - "}")); - } - - @Test - public void testArrow() { - assertChanges( - LINE_JOINER.join( - "goog.bind(() => {", - " console.log('hello');", - "}, this)"), - LINE_JOINER.join( - "() => {", - " console.log('hello');", - "}")); - } - - @Test - public void testFunctionWithReturn() { - assertChanges( - LINE_JOINER.join( - "goog.bind(function() {", - " console.log('hello world');", - " return false;", - "}, this)"), - LINE_JOINER.join( - "() => {", - " console.log('hello world');", - " return false;", - "}")); - } - - @Test - public void testSimpleReturn() { - assertChanges( - LINE_JOINER.join( - "goog.bind(function() {", - " return 7;", - "}, this)"), - "() => 7"); - - assertChanges( - LINE_JOINER.join( - "[1,2,3].forEach(goog.bind(function(x) {", // - " return y;", - "}, this));"), - "[1,2,3].forEach(x => y);"); - } - - /** - * Test to show the bad indentation that we're getting. - * @bug 25514142 - */ - @Test - public void testIndentation() { - assertChanges( - LINE_JOINER.join( - "if (x) {", - " if (y) {", - " var f = goog.bind(function() {", - " alert(x);", - " alert(y);", - " }, this);", - " }", - "}"), - LINE_JOINER.join( - "if (x) {", - " if (y) {", - " var f = () => {", - " alert(x);", - " alert(y);", - "};", - " }", - "}")); - } - - @Test - public void testNoChanges() { - assertNoChanges("goog.bind(function() {}, foo)"); - assertNoChanges("goog.bind(fn, this)"); - } -} diff --git a/test/com/google/javascript/refactoring/examples/StringIndexOfToIncludesTest.java b/test/com/google/javascript/refactoring/examples/StringIndexOfToIncludesTest.java deleted file mode 100644 index 186ef41c010..00000000000 --- a/test/com/google/javascript/refactoring/examples/StringIndexOfToIncludesTest.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2017 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.refactoring.examples; - -import com.google.javascript.refactoring.testing.RefasterJsTestCase; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -@RunWith(JUnit4.class) -public class StringIndexOfToIncludesTest { - - /** Path of the directory containing test inputs and expected outputs. */ - private static final String TESTDATA_DIR = - "test/" - + "com/google/javascript/refactoring/examples/testdata"; - - /** The RefasterJs template to use. */ - private static final String STRING_INDEXOF_TO_INCLUDES_TEMPLATE = - "com/google/javascript/refactoring/examples/refasterjs/string_indexof_to_includes.js"; - - @Test - public void test_refactorings() throws Exception { - RefasterJsTestCase.builder() - .setTemplatePath(STRING_INDEXOF_TO_INCLUDES_TEMPLATE) - .setInputPath(TESTDATA_DIR + "/string_indexof_to_includes_in.js") - .addExpectedOutputPath(TESTDATA_DIR + "/string_indexof_to_includes_out.js") - .addAdditionalSourcePath(TESTDATA_DIR + "/goog_base.js") - .test(); - } -} diff --git a/test/com/google/javascript/refactoring/examples/security/NavigationalXssSinksRefactoringTest.java b/test/com/google/javascript/refactoring/examples/security/NavigationalXssSinksRefactoringTest.java deleted file mode 100644 index 451ad470af4..00000000000 --- a/test/com/google/javascript/refactoring/examples/security/NavigationalXssSinksRefactoringTest.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2016 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.refactoring.examples.security; - -import com.google.javascript.refactoring.testing.RefasterJsTestCase; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -@RunWith(JUnit4.class) -public class NavigationalXssSinksRefactoringTest { - - /** Path of the directory containing test inputs and expected outputs. */ - private static final String TESTDATA_DIR = - "test/" - + "com/google/javascript/refactoring/examples/security/testdata"; - - /** The RefasterJs template to use. */ - private static final String NAVIGATIONAL_XSS_SINKS_TEMPLATE = - "com/google/javascript/refactoring/examples/refasterjs/security/navigational_xss_sinks.js"; - - @Test - public void test_refactorings() throws Exception { - RefasterJsTestCase.builder() - .setTemplatePath(NAVIGATIONAL_XSS_SINKS_TEMPLATE) - .setInputPath(TESTDATA_DIR + "/navigational_xss_sinks_test_in.js") - .addExpectedOutputPath(TESTDATA_DIR + "/navigational_xss_sinks_test_out.js") - .addAdditionalSourcePath(TESTDATA_DIR + "/goog_base.js") - .test(); - } - - @Test - public void testModuleRefactoring() throws Exception { - RefasterJsTestCase.builder() - .setTemplatePath(NAVIGATIONAL_XSS_SINKS_TEMPLATE) - .setInputPath(TESTDATA_DIR + "/navigational_xss_sinks_test_module_in.js") - .addExpectedOutputPath(TESTDATA_DIR + "/navigational_xss_sinks_test_module_out.js") - .addAdditionalSourcePath(TESTDATA_DIR + "/goog_base.js") - .addAdditionalSourcePath(TESTDATA_DIR + "/goog_foo.js") - .test(); - } -} diff --git a/test/com/google/javascript/refactoring/examples/security/SetLocationTest.java b/test/com/google/javascript/refactoring/examples/security/SetLocationTest.java deleted file mode 100644 index e622a20df4e..00000000000 --- a/test/com/google/javascript/refactoring/examples/security/SetLocationTest.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2016 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.refactoring.examples.security; - -import com.google.javascript.refactoring.testing.RefasterJsTestCase; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -@RunWith(JUnit4.class) -public class SetLocationTest { - - /** Path of the directory containing test inputs and expected outputs. */ - private static final String TESTDATA_DIR = - "test/" - + "com/google/javascript/refactoring/examples/security/testdata"; - - /** The RefasterJs template to use for Location#href. */ - private static final String SET_LOCATION_HREF_TEMPLATE = - "com/google/javascript/refactoring/examples/refasterjs/security/set_location_href.js"; - - /** The RefasterJs template to use for Window#location. */ - private static final String SET_WINDOW_LOCATION_TEMPLATE = - "com/google/javascript/refactoring/examples/refasterjs/security/set_window_location.js"; - - @Test - public void testLocationHref() throws Exception { - RefasterJsTestCase.builder() - .setTemplatePath(SET_LOCATION_HREF_TEMPLATE) - .setInputPath(TESTDATA_DIR + "/set_location_href_test_in.js") - .addExpectedOutputPath(TESTDATA_DIR + "/set_location_href_test_out.js") - .addAdditionalSourcePath(TESTDATA_DIR + "/goog_base.js") - .test(); - } - - @Test - public void testWindowLocation() throws Exception { - RefasterJsTestCase.builder() - .setTemplatePath(SET_WINDOW_LOCATION_TEMPLATE) - .setInputPath(TESTDATA_DIR + "/set_window_location_test_in.js") - .addExpectedOutputPath(TESTDATA_DIR + "/set_window_location_test_out.js") - .addAdditionalSourcePath(TESTDATA_DIR + "/goog_base.js") - .test(); - } -} diff --git a/test/com/google/javascript/refactoring/examples/security/testdata/goog_base.js b/test/com/google/javascript/refactoring/examples/security/testdata/goog_base.js deleted file mode 100644 index df313374f3e..00000000000 --- a/test/com/google/javascript/refactoring/examples/security/testdata/goog_base.js +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2016 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. - */ - -/** @fileoverview Required pieces of Closure's base.js . */ - -/** @const */ -var goog = goog || {}; - -/** @param {string} name */ -goog.provide = function(name) {}; - -/** @param {string} name */ -goog.require = function(name) {}; - -/** @param {string} name */ -goog.module = function(name) {}; diff --git a/test/com/google/javascript/refactoring/examples/security/testdata/goog_foo.js b/test/com/google/javascript/refactoring/examples/security/testdata/goog_foo.js deleted file mode 100644 index 2e75a157ba1..00000000000 --- a/test/com/google/javascript/refactoring/examples/security/testdata/goog_foo.js +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2016 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. - */ - -/** @fileoverview Mock namespace . */ - -goog.module('goog.foo'); - -/** Does nothing. */ -exports.bar = function() {}; diff --git a/test/com/google/javascript/refactoring/examples/security/testdata/navigational_xss_sinks_test_in.js b/test/com/google/javascript/refactoring/examples/security/testdata/navigational_xss_sinks_test_in.js deleted file mode 100644 index 1a70e96a541..00000000000 --- a/test/com/google/javascript/refactoring/examples/security/testdata/navigational_xss_sinks_test_in.js +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright 2016 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. - */ - -/** - * @fileoverview Test cases for the navigational_xss_sinks.js RefasterJs - * template. - */ - -goog.provide('refactoring_testcase'); - -// -// Test cases for .href assignments in well-typed contexts. -// - -/** - * @param {!Location} target The target. - * @param {string} val The value. - */ -refactoring_testcase.nonnull_location_href = function(target, val) { - // Should match before_setLocationHref. - target.href = val; -}; - -/** - * @param {?Location} target The target. - * @param {string} val The value. - */ -refactoring_testcase.nullable_location_href = function(target, val) { - // Should match before_setLocationHrefNullable. - target.href = val; -}; - -// -// Test case for matching string literals -// - -/** - * @param {!Location} target The target. - */ -refactoring_testcase.href_string_literal = function(target) { - // Should match do_not_change_setHrefStringLiteral. - target.href = 'about:blank'; -}; - -// -// Test cases for .href assignments that match the un-typed catch-all rule. -// - - -/** - * @param {!Location|!Element} target The target. - * @param {string} val The value. - */ -refactoring_testcase.union_type_href = function(target, val) { - // Should match before_setHrefUnknown. - target.href = val; -}; - -/** - * @param {?} targetElement The target. - * @param {string} val The value. - */ -refactoring_testcase.unknowntype_href = function(targetElement, val) { - // Should match before_setHrefUnknown. - targetElement.href = val; -}; - -// -// Test cases for .location assignments in well-typed contexts. -// - -/** - * @param {!Window} target The target. - * @param {string} val The value. - */ -refactoring_testcase.window_location = function(target, val) { - // Should match before_setWindowLocation. - target.location = val; -}; - -/** - * @param {?Window} target The target. - * @param {string} val The value. - */ -refactoring_testcase.window_location_nullable = function(target, val) { - // Should match before_setWindowLocation. - target.location = val; -}; - -/** - * @param {!Document} target The target. - * @param {string} val The value. - */ -refactoring_testcase.document_location = function(target, val) { - // Should match before_setDocumentLocation. - target.location = val; -}; - -/** - * @param {?Document} target The target. - * @param {string} val The value. - */ -refactoring_testcase.document_location_nullable = function(target, val) { - // Should match before_setDocumentLocation. - target.location = val; -}; - -/** - * @param {?HTMLDocument} target The target. - * @param {string} val The value. - */ -refactoring_testcase.document_location_subtype = function(target, val) { - // Should match before_setDocumentLocation since {?HTMLDocument} is a subtype - // of {?Document}. - target.location = val; -}; - -// -// Test cases for .location assignments in poorly-typed contexts. -// - -/** - * @param {?} target The target. - * @param {string} val The value. - */ -refactoring_testcase.unknown_location = function(target, val) { - // Should match before_setLocationUnknown. - target.location = val; -}; - -/** - * @param {!Object} target The target. - * @param {string} val The value. - */ -refactoring_testcase.object_location = function(target, val) { - // Should match before_setLocationUnknown. - target.location = val; -}; - - -/** - * @param {*} target The target. - * @param {string} val The value. - */ -refactoring_testcase.any_location = function(target, val) { - // Should match before_setLocationUnknown. - target.location = val; -}; diff --git a/test/com/google/javascript/refactoring/examples/security/testdata/navigational_xss_sinks_test_module_in.js b/test/com/google/javascript/refactoring/examples/security/testdata/navigational_xss_sinks_test_module_in.js deleted file mode 100644 index 409b12e820a..00000000000 --- a/test/com/google/javascript/refactoring/examples/security/testdata/navigational_xss_sinks_test_module_in.js +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2016 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. - */ - -/** - * @fileoverview Test cases for the navigational_xss_sinks.js RefasterJs - * template. - */ - -goog.module('refactoring_testcase'); -const foo = goog.require('goog.foo'); - -/** - * @param {!Location} target The target. - * @param {string} val The value. - */ -exports.nonnull_location_href = function(target, val) { - foo.bar(); - // Should match before_setLocationHref. - target.href = val; -}; diff --git a/test/com/google/javascript/refactoring/examples/security/testdata/navigational_xss_sinks_test_module_out.js b/test/com/google/javascript/refactoring/examples/security/testdata/navigational_xss_sinks_test_module_out.js deleted file mode 100644 index b8d6543b762..00000000000 --- a/test/com/google/javascript/refactoring/examples/security/testdata/navigational_xss_sinks_test_module_out.js +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2016 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. - */ - -/** - * @fileoverview Test cases for the navigational_xss_sinks.js RefasterJs - * template. - */ - -goog.module('refactoring_testcase'); -const foo = goog.require('goog.foo'); -const safe = goog.require('goog.dom.safe'); - -/** - * @param {!Location} target The target. - * @param {string} val The value. - */ -exports.nonnull_location_href = function(target, val) { - foo.bar(); - // Should match before_setLocationHref. - safe.setLocationHref(target, val); -}; diff --git a/test/com/google/javascript/refactoring/examples/security/testdata/navigational_xss_sinks_test_out.js b/test/com/google/javascript/refactoring/examples/security/testdata/navigational_xss_sinks_test_out.js deleted file mode 100644 index b2e0b7931b5..00000000000 --- a/test/com/google/javascript/refactoring/examples/security/testdata/navigational_xss_sinks_test_out.js +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright 2016 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. - */ - -/** - * @fileoverview Test cases for the navigational_xss_sinks.js RefasterJs - * template. - */ - -goog.provide('refactoring_testcase'); -goog.require('goog.asserts'); -goog.require('goog.dom.safe'); - -// -// Test cases for .href assignments in well-typed contexts. -// - -/** - * @param {!Location} target The target. - * @param {string} val The value. - */ -refactoring_testcase.nonnull_location_href = function(target, val) { - // Should match before_setLocationHref. - goog.dom.safe.setLocationHref(target, val); -}; - -/** - * @param {?Location} target The target. - * @param {string} val The value. - */ -refactoring_testcase.nullable_location_href = function(target, val) { - // Should match before_setLocationHrefNullable. - goog.dom.safe.setLocationHref(goog.asserts.assert(target), val); -}; - -// -// Test case for matching string literals -// - -/** - * @param {!Location} target The target. - */ -refactoring_testcase.href_string_literal = function(target) { - // Should match do_not_change_setHrefStringLiteral. - target.href = 'about:blank'; -}; - -// -// Test cases for .href assignments that match the un-typed catch-all rule. -// - - -/** - * @param {!Location|!Element} target The target. - * @param {string} val The value. - */ -refactoring_testcase.union_type_href = function(target, val) { - // Should match before_setHrefUnknown. - goog.dom.safe.setLocationHref(goog.asserts.assertInstanceof(requiresReview(target), Location), val); -}; - -/** - * @param {?} targetElement The target. - * @param {string} val The value. - */ -refactoring_testcase.unknowntype_href = function(targetElement, val) { - // Should match before_setHrefUnknown. - goog.dom.safe.setLocationHref(goog.asserts.assertInstanceof(requiresReview(targetElement), Location), val); -}; - -// -// Test cases for .location assignments in well-typed contexts. -// - -/** - * @param {!Window} target The target. - * @param {string} val The value. - */ -refactoring_testcase.window_location = function(target, val) { - // Should match before_setWindowLocation. - goog.dom.safe.setLocationHref(target.location, val); -}; - -/** - * @param {?Window} target The target. - * @param {string} val The value. - */ -refactoring_testcase.window_location_nullable = function(target, val) { - // Should match before_setWindowLocation. - goog.dom.safe.setLocationHref(target.location, val); -}; - -/** - * @param {!Document} target The target. - * @param {string} val The value. - */ -refactoring_testcase.document_location = function(target, val) { - // Should match before_setDocumentLocation. - goog.dom.safe.setLocationHref(target.location, val); -}; - -/** - * @param {?Document} target The target. - * @param {string} val The value. - */ -refactoring_testcase.document_location_nullable = function(target, val) { - // Should match before_setDocumentLocation. - goog.dom.safe.setLocationHref(target.location, val); -}; - -/** - * @param {?HTMLDocument} target The target. - * @param {string} val The value. - */ -refactoring_testcase.document_location_subtype = function(target, val) { - // Should match before_setDocumentLocation since {?HTMLDocument} is a subtype - // of {?Document}. - goog.dom.safe.setLocationHref(target.location, val); -}; - -// -// Test cases for .location assignments in poorly-typed contexts. -// - -/** - * @param {?} target The target. - * @param {string} val The value. - */ -refactoring_testcase.unknown_location = function(target, val) { - // Should match before_setLocationUnknown. - goog.dom.safe.setLocationHref(goog.asserts.assertInstanceof(requiresReview(target), Window).location, val); -}; - -/** - * @param {!Object} target The target. - * @param {string} val The value. - */ -refactoring_testcase.object_location = function(target, val) { - // Should match before_setLocationUnknown. - goog.dom.safe.setLocationHref(goog.asserts.assertInstanceof(requiresReview(target), Window).location, val); -}; - - -/** - * @param {*} target The target. - * @param {string} val The value. - */ -refactoring_testcase.any_location = function(target, val) { - // Should match before_setLocationUnknown. - goog.dom.safe.setLocationHref(goog.asserts.assertInstanceof(requiresReview(target), Window).location, val); -}; diff --git a/test/com/google/javascript/refactoring/examples/security/testdata/set_location_href_test_in.js b/test/com/google/javascript/refactoring/examples/security/testdata/set_location_href_test_in.js deleted file mode 100644 index b82ff8bcb46..00000000000 --- a/test/com/google/javascript/refactoring/examples/security/testdata/set_location_href_test_in.js +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2016 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. - */ - -/** @fileoverview Test cases for set_location_href RefasterJs template. */ - -goog.provide('refactoring_testcase'); - - -/** - * @param {!Location} target The target. - * @param {string} val The value. - */ -refactoring_testcase.test_location_href = function(target, val) { - // Should match. - target.href = val; -}; - -/** - * @param {!Location} target The Target. - */ -refactoring_testcase.location_href_string_literal = function(target) { - // Shouldn't match. - target.href = 'foo'; -}; - -/** - * @param {!Location|!Element} target The target. - * @param {string} val The value. - */ -refactoring_testcase.union_type_href = function(target, val) { - // Shouldn't match. - target.href = val; -}; - -/** - * @param {!Window|!Element} target The target. - * @param {string} val The value. - */ -refactoring_testcase.union_type_location = function(target, val) { - // Shouldn't match. - target.location = val; -}; diff --git a/test/com/google/javascript/refactoring/examples/security/testdata/set_location_href_test_out.js b/test/com/google/javascript/refactoring/examples/security/testdata/set_location_href_test_out.js deleted file mode 100644 index fd035698849..00000000000 --- a/test/com/google/javascript/refactoring/examples/security/testdata/set_location_href_test_out.js +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2016 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. - */ - -/** @fileoverview Test cases for set_location_href RefasterJs template. */ - -goog.provide('refactoring_testcase'); -goog.require('goog.dom.safe'); - - -/** - * @param {!Location} target The target. - * @param {string} val The value. - */ -refactoring_testcase.test_location_href = function(target, val) { - // Should match. - goog.dom.safe.setLocationHref(target, val); -}; - -/** - * @param {!Location} target The Target. - */ -refactoring_testcase.location_href_string_literal = function(target) { - // Shouldn't match. - target.href = 'foo'; -}; - -/** - * @param {!Location|!Element} target The target. - * @param {string} val The value. - */ -refactoring_testcase.union_type_href = function(target, val) { - // Shouldn't match. - target.href = val; -}; - -/** - * @param {!Window|!Element} target The target. - * @param {string} val The value. - */ -refactoring_testcase.union_type_location = function(target, val) { - // Shouldn't match. - target.location = val; -}; diff --git a/test/com/google/javascript/refactoring/examples/security/testdata/set_window_location_test_in.js b/test/com/google/javascript/refactoring/examples/security/testdata/set_window_location_test_in.js deleted file mode 100644 index 38925261a45..00000000000 --- a/test/com/google/javascript/refactoring/examples/security/testdata/set_window_location_test_in.js +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2016 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. - */ - -/** @fileoverview Test cases for set_location_href RefasterJs template. */ - -goog.provide('refactoring_testcase'); - -/** - * @param {!Window} target The target. - * @param {string} val The value. - */ -refactoring_testcase.test_window_location = function(target, val) { - // Should match. - target.location = val; -}; - -/** - * @param {!Window|!Element} target The target. - * @param {string} val The value. - */ -refactoring_testcase.union_type_location = function(target, val) { - // Shouldn't match. - target.location = val; -}; diff --git a/test/com/google/javascript/refactoring/examples/security/testdata/set_window_location_test_out.js b/test/com/google/javascript/refactoring/examples/security/testdata/set_window_location_test_out.js deleted file mode 100644 index 948c750db9f..00000000000 --- a/test/com/google/javascript/refactoring/examples/security/testdata/set_window_location_test_out.js +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2016 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. - */ - -/** @fileoverview Test cases for set_location_href RefasterJs template. */ - -goog.provide('refactoring_testcase'); -goog.require('goog.dom.safe'); - -/** - * @param {!Window} target The target. - * @param {string} val The value. - */ -refactoring_testcase.test_window_location = function(target, val) { - // Should match. - goog.dom.safe.setLocationHref(target.location, val); -}; - -/** - * @param {!Window|!Element} target The target. - * @param {string} val The value. - */ -refactoring_testcase.union_type_location = function(target, val) { - // Shouldn't match. - target.location = val; -}; diff --git a/test/com/google/javascript/refactoring/examples/testdata/array_indexof_to_includes_in.js b/test/com/google/javascript/refactoring/examples/testdata/array_indexof_to_includes_in.js deleted file mode 100644 index 1add37609ea..00000000000 --- a/test/com/google/javascript/refactoring/examples/testdata/array_indexof_to_includes_in.js +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright 2017 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. - */ - -/** - * @fileoverview Test cases for array_indexof_to_includes RefasterJs template. - * @suppress {unusedLocalVariables} - */ - -goog.provide('refactoring_testcase'); - - -/** - * @param {!Array} arr The array. - * @param {string} elem The element to check. - * @return {boolean} Whether the element is in the array. - */ -refactoring_testcase.not_equals_minus_one = function(arr, elem) { - const arrA = [3]; - const foundA = arrA.indexOf(1) != -1; - - const arrB = []; - arrB.push('str'); - const foundB = arrB.indexOf('s') != -1; - - return arr.indexOf(elem) != -1; -}; - -/** - * @param {!Array} arr The array. - * @param {string} elem The element to check. - * @return {boolean} Whether the element is in the array. - */ -refactoring_testcase.not_strongly_equals_minus_one = function(arr, elem) { - const arrA = [3]; - const foundA = arrA.indexOf(1) !== -1; - - const arrB = []; - arrB.push('str'); - const foundB = arrB.indexOf('s') !== -1; - - return arr.indexOf(elem) !== -1; -}; - -/** - * @param {!Array} arr The array. - * @param {string} elem The element to check. - * @return {boolean} Whether the element is in the array. - */ -refactoring_testcase.greater_than_minus_one = function(arr, elem) { - const arrA = [3]; - const foundA = arrA.indexOf(1) > -1; - - const arrB = []; - arrB.push('str'); - const foundB = arrB.indexOf('s') > -1; - - return arr.indexOf(elem) > -1; -}; - -/** - * @param {!Array} arr The array. - * @param {string} elem The element to check. - * @return {boolean} Whether the element is in the array. - */ -refactoring_testcase.greater_than_or_equals_zero = function(arr, elem) { - const arrA = [3]; - const foundA = arrA.indexOf(1) >= 0; - - const arrB = []; - arrB.push('str'); - const foundB = arrB.indexOf('s') >= 0; - - return arr.indexOf(elem) >= 0; -}; - -/** - * @param {!Array} arr The array. - * @param {string} elem The element to check. - * @return {boolean} Whether the element is in the array. - */ -refactoring_testcase.equals_minus_one = function(arr, elem) { - const arrA = [3]; - const foundA = arrA.indexOf(1) == -1; - - const arrB = []; - arrB.push('str'); - const foundB = arrB.indexOf('s') == -1; - - return arr.indexOf(elem) == -1; -}; - -/** - * @param {!Array} arr The array. - * @param {string} elem The element to check. - * @return {boolean} Whether the element is in the array. - */ -refactoring_testcase.strongly_equals_minus_one = function(arr, elem) { - const arrA = [3]; - const foundA = arrA.indexOf(1) === -1; - - const arrB = []; - arrB.push('str'); - const foundB = arrB.indexOf('s') === -1; - - return arr.indexOf(elem) === -1; -}; - -/** - * @param {!Array} arr The array. - * @param {string} elem The element to check. - * @return {boolean} Whether the element is in the array. - */ -refactoring_testcase.less_than_zero = function(arr, elem) { - const arrA = [3]; - const foundA = arrA.indexOf(1) < 0; - - const arrB = []; - arrB.push('str'); - const foundB = arrB.indexOf('s') < 0; - - return arr.indexOf(elem) < 0; -}; - -/** - * @param {!Array} arr The array. - * @param {string} elem The element to check. - * @return {number|boolean} Whether the element is in the array. - * Returns true/truthy if the value is found, false/falsy otherwise. - */ -refactoring_testcase.bitwise_not = function(arr, elem) { - const arrA = [3]; - const foundA = ~arrA.indexOf(1); - - const arrB = []; - arrB.push('str'); - const foundB = ~arrB.indexOf('s'); - - return ~arr.indexOf(elem); -}; - -/** - * The refactoring should ignore calls to indexOf on non-array objects. - * @param {string} str A string. - * @param {string} subStr The substring to check. - * @return {boolean} Whether the substring is in the array. - */ -refactoring_testcase.ignore_non_arrays = function(str, subStr) { - const strA = 'abc'; - strA.indexOf('z'); - const indexOfZ = 'xyz'.indexOf('z') == 2; - - // method in object. - const objA = {indexOf: function(a) {}}; - objA.indexOf(''); - - // shorthand method names. - const objB = {indexOf(a) {}}; - objB.indexOf(''); - - return str.indexOf(subStr) != -1; -}; diff --git a/test/com/google/javascript/refactoring/examples/testdata/array_indexof_to_includes_out.js b/test/com/google/javascript/refactoring/examples/testdata/array_indexof_to_includes_out.js deleted file mode 100644 index c451dfea982..00000000000 --- a/test/com/google/javascript/refactoring/examples/testdata/array_indexof_to_includes_out.js +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright 2017 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. - */ - -/** - * @fileoverview Test cases for array_indexof_to_includes RefasterJs template. - * @suppress {unusedLocalVariables} - */ - -goog.provide('refactoring_testcase'); - - -/** - * @param {!Array} arr The array. - * @param {string} elem The element to check. - * @return {boolean} Whether the element is in the array. - */ -refactoring_testcase.not_equals_minus_one = function(arr, elem) { - const arrA = [3]; - const foundA = arrA.includes(1); - - const arrB = []; - arrB.push('str'); - const foundB = arrB.includes('s'); - - return arr.includes(elem); -}; - -/** - * @param {!Array} arr The array. - * @param {string} elem The element to check. - * @return {boolean} Whether the element is in the array. - */ -refactoring_testcase.not_strongly_equals_minus_one = function(arr, elem) { - const arrA = [3]; - const foundA = arrA.includes(1); - - const arrB = []; - arrB.push('str'); - const foundB = arrB.includes('s'); - - return arr.includes(elem); -}; - -/** - * @param {!Array} arr The array. - * @param {string} elem The element to check. - * @return {boolean} Whether the element is in the array. - */ -refactoring_testcase.greater_than_minus_one = function(arr, elem) { - const arrA = [3]; - const foundA = arrA.includes(1); - - const arrB = []; - arrB.push('str'); - const foundB = arrB.includes('s'); - - return arr.includes(elem); -}; - -/** - * @param {!Array} arr The array. - * @param {string} elem The element to check. - * @return {boolean} Whether the element is in the array. - */ -refactoring_testcase.greater_than_or_equals_zero = function(arr, elem) { - const arrA = [3]; - const foundA = arrA.includes(1); - - const arrB = []; - arrB.push('str'); - const foundB = arrB.includes('s'); - - return arr.includes(elem); -}; - -/** - * @param {!Array} arr The array. - * @param {string} elem The element to check. - * @return {boolean} Whether the element is in the array. - */ -refactoring_testcase.equals_minus_one = function(arr, elem) { - const arrA = [3]; - const foundA = !arrA.includes(1); - - const arrB = []; - arrB.push('str'); - const foundB = !arrB.includes('s'); - - return !arr.includes(elem); -}; - -/** - * @param {!Array} arr The array. - * @param {string} elem The element to check. - * @return {boolean} Whether the element is in the array. - */ -refactoring_testcase.strongly_equals_minus_one = function(arr, elem) { - const arrA = [3]; - const foundA = !arrA.includes(1); - - const arrB = []; - arrB.push('str'); - const foundB = !arrB.includes('s'); - - return !arr.includes(elem); -}; - -/** - * @param {!Array} arr The array. - * @param {string} elem The element to check. - * @return {boolean} Whether the element is in the array. - */ -refactoring_testcase.less_than_zero = function(arr, elem) { - const arrA = [3]; - const foundA = !arrA.includes(1); - - const arrB = []; - arrB.push('str'); - const foundB = !arrB.includes('s'); - - return !arr.includes(elem); -}; - -/** - * @param {!Array} arr The array. - * @param {string} elem The element to check. - * @return {number|boolean} Whether the element is in the array. - * Returns true/truthy if the value is found, false/falsy otherwise. - */ -refactoring_testcase.bitwise_not = function(arr, elem) { - const arrA = [3]; - const foundA = arrA.includes(1); - - const arrB = []; - arrB.push('str'); - const foundB = arrB.includes('s'); - - return arr.includes(elem); -}; - -/** - * The refactoring should ignore calls to indexOf on non-array objects. - * @param {string} str A string. - * @param {string} subStr The substring to check. - * @return {boolean} Whether the substring is in the array. - */ -refactoring_testcase.ignore_non_arrays = function(str, subStr) { - const strA = 'abc'; - strA.indexOf('z'); - const indexOfZ = 'xyz'.indexOf('z') == 2; - - // method in object. - const objA = {indexOf: function(a) {}}; - objA.indexOf(''); - - // shorthand method names. - const objB = {indexOf(a) {}}; - objB.indexOf(''); - - return str.indexOf(subStr) != -1; -}; diff --git a/test/com/google/javascript/refactoring/examples/testdata/array_prototype_slice_to_array_from_in.js b/test/com/google/javascript/refactoring/examples/testdata/array_prototype_slice_to_array_from_in.js deleted file mode 100644 index 9c8531081c6..00000000000 --- a/test/com/google/javascript/refactoring/examples/testdata/array_prototype_slice_to_array_from_in.js +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2017 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. - */ - -/** - * @fileoverview Test cases for array_prototype_slice_to_array_from RefasterJs - * template. - * @suppress {unusedLocalVariables} - */ - -goog.provide('refactoring_testcase'); - -/** - * @param {!IArrayLike} arrLike The array-like object. - */ -refactoring_testcase.slice_no_args = function(arrLike) { - // Generic array-like object. - Array.prototype.slice.call(arrLike); - - // HTMLCollection. - Array.prototype.slice.call(document.forms); - - // NodeList. - Array.prototype.slice.call(document.querySelectorAll('*')); - - // Array. - Array.prototype.slice.call([1, 2]); - - // String. - Array.prototype.slice.call('string'); -}; - -/** - * @param {!IArrayLike} arrLike The array-like object. - */ -refactoring_testcase.slice_zero = function(arrLike) { - // Generic array-like object. - Array.prototype.slice.call(arrLike, 0); - - // HTMLCollection. - Array.prototype.slice.call(document.forms, 0); - - // NodeList. - Array.prototype.slice.call(document.querySelectorAll('*'), 0); - - // Array. - Array.prototype.slice.call([1, 2], 0); - - // String. - Array.prototype.slice.call('string'); -}; - -/** - * Ignore other types that are not array-like objects. - */ -refactoring_testcase.ignore_other_types = function() { - // null. - Array.prototype.slice.call(null); - Array.prototype.slice.call(null, 0); - - // undefined. - Array.prototype.slice.call(undefined); - Array.prototype.slice.call(undefined, 0); -}; diff --git a/test/com/google/javascript/refactoring/examples/testdata/array_prototype_slice_to_array_from_out.js b/test/com/google/javascript/refactoring/examples/testdata/array_prototype_slice_to_array_from_out.js deleted file mode 100644 index 18216bfa95c..00000000000 --- a/test/com/google/javascript/refactoring/examples/testdata/array_prototype_slice_to_array_from_out.js +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2017 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. - */ - -/** - * @fileoverview Test cases for array_prototype_slice_to_array_from RefasterJs - * template. - * @suppress {unusedLocalVariables} - */ - -goog.provide('refactoring_testcase'); - -/** - * @param {!IArrayLike} arrLike The array-like object. - */ -refactoring_testcase.slice_no_args = function(arrLike) { - // Generic array-like object. - Array.from(arrLike); - - // HTMLCollection. - Array.from(document.forms); - - // NodeList. - Array.from(document.querySelectorAll('*')); - - // Array. - Array.from([1, 2]); - - // String. - Array.from('string'); -}; - -/** - * @param {!IArrayLike} arrLike The array-like object. - */ -refactoring_testcase.slice_zero = function(arrLike) { - // Generic array-like object. - Array.from(arrLike); - - // HTMLCollection. - Array.from(document.forms); - - // NodeList. - Array.from(document.querySelectorAll('*')); - - // Array. - Array.from([1, 2]); - - // String. - Array.from('string'); -}; - -/** - * Ignore other types that are not array-like objects. - */ -refactoring_testcase.ignore_other_types = function() { - // null. - Array.prototype.slice.call(null); - Array.prototype.slice.call(null, 0); - - // undefined. - Array.prototype.slice.call(undefined); - Array.prototype.slice.call(undefined, 0); -}; diff --git a/test/com/google/javascript/refactoring/examples/testdata/chai_expect_to_assert_in.js b/test/com/google/javascript/refactoring/examples/testdata/chai_expect_to_assert_in.js deleted file mode 100644 index 916031db076..00000000000 --- a/test/com/google/javascript/refactoring/examples/testdata/chai_expect_to_assert_in.js +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2017 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. - */ - -/** - * @fileoverview - * @suppress {uselessCode} - */ - -var someVar; - -/** Example test */ -function mathTest() { - expect(1 > 0).to.be.true; - expect(2 < 0).to.be.false; -} - -/** - * Another example - * @suppress {suspiciousCode} false || null - */ -function nullAndUndefinedTest() { - expect(false || null).to.be.null; - expect(someVar).to.be.undefined; -} - -/** Truthiness! */ -function okTest() { - expect('a string').to.be.ok; -} - -/** - * The .to.not.be variations. - * @suppress {suspiciousCode} false || null - */ -function negativeTest() { - expect(1 > 0).to.not.be.true; - expect(2 < 0).to.not.be.false; - expect(false || null).to.not.be.null; - expect(someVar).to.not.be.undefined; - expect('a string').to.not.be.ok; -} - -/** Tests method (not property) expectations */ -function methodTests() { - expect(1 + 1).to.equal(2); - expect(1 + 1).to.not.equal(3); - expect(1 + 1).not.to.equal(3); - expect([1, 2]).to.deep.equal([1, 2]); - expect([1, 2]).to.not.deep.equal([2, 1]); - expect([]).is.an.instanceof(Array); - expect([]).to.be.an.instanceof(Array); - expect(1).to.be.oneOf([2, 1]); - expect([1, 2]).to.contain(1); - expect([1, 2]).to.have.lengthOf(2); -} diff --git a/test/com/google/javascript/refactoring/examples/testdata/chai_expect_to_assert_out.js b/test/com/google/javascript/refactoring/examples/testdata/chai_expect_to_assert_out.js deleted file mode 100644 index e403b5f1593..00000000000 --- a/test/com/google/javascript/refactoring/examples/testdata/chai_expect_to_assert_out.js +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2017 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. - */ - -/** - * @fileoverview - * @suppress {uselessCode} - */ - -var someVar; - -/** Example test */ -function mathTest() { - assert.isTrue(1 > 0); - assert.isFalse(2 < 0); -} - -/** - * Another example - * @suppress {suspiciousCode} false || null - */ -function nullAndUndefinedTest() { - assert.isNull(false || null); - assert.isUndefined(someVar); -} - -/** Truthiness! */ -function okTest() { - assert.isOk('a string'); -} - -/** - * The .to.not.be variations. - * @suppress {suspiciousCode} false || null - */ -function negativeTest() { - assert.isNotTrue(1 > 0); - assert.isNotFalse(2 < 0); - assert.isNotNull(false || null); - assert.isDefined(someVar); - assert.isNotOk('a string'); -} - -/** Tests method (not property) expectations */ -function methodTests() { - assert.equal(1 + 1, 2); - assert.notEqual(1 + 1, 3); - assert.notEqual(1 + 1, 3); - assert.deepEqual([1, 2], [1, 2]); - assert.notDeepEqual([1, 2], [2, 1]); - assert.instanceOf([], Array); - assert.instanceOf([], Array); - assert.oneOf(1, [2, 1]); - assert.include([1, 2], 1); - assert.lengthOf([1, 2], 2); -} diff --git a/test/com/google/javascript/refactoring/examples/testdata/goog_base.js b/test/com/google/javascript/refactoring/examples/testdata/goog_base.js deleted file mode 100644 index df313374f3e..00000000000 --- a/test/com/google/javascript/refactoring/examples/testdata/goog_base.js +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2016 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. - */ - -/** @fileoverview Required pieces of Closure's base.js . */ - -/** @const */ -var goog = goog || {}; - -/** @param {string} name */ -goog.provide = function(name) {}; - -/** @param {string} name */ -goog.require = function(name) {}; - -/** @param {string} name */ -goog.module = function(name) {}; diff --git a/test/com/google/javascript/refactoring/examples/testdata/goog_foo.js b/test/com/google/javascript/refactoring/examples/testdata/goog_foo.js deleted file mode 100644 index 2e75a157ba1..00000000000 --- a/test/com/google/javascript/refactoring/examples/testdata/goog_foo.js +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2016 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. - */ - -/** @fileoverview Mock namespace . */ - -goog.module('goog.foo'); - -/** Does nothing. */ -exports.bar = function() {}; diff --git a/test/com/google/javascript/refactoring/examples/testdata/string_indexof_to_includes_in.js b/test/com/google/javascript/refactoring/examples/testdata/string_indexof_to_includes_in.js deleted file mode 100644 index ae7cd1bed3c..00000000000 --- a/test/com/google/javascript/refactoring/examples/testdata/string_indexof_to_includes_in.js +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright 2017 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. - */ - -/** - * @fileoverview Test cases for string_indexof_to_includes RefasterJs template. - * @suppress {unusedLocalVariables} - */ - -goog.provide('refactoring_testcase'); - - -/** - * @param {string} str The string. - * @param {string} subStr The sub-string to check. - * @return {boolean} Whether the sub-string is found the string. - */ -refactoring_testcase.not_equals_minus_one = function(str, subStr) { - const strA = 'abc'; - const foundA = strA.indexOf('b') != -1; - - const foundB = 'xyz'.indexOf('x') != -1; - - return str.indexOf(subStr) != -1; -}; - -/** - * @param {string} str The string. - * @param {string} subStr The sub-string to check. - * @return {boolean} Whether the sub-string is found the string. - */ -refactoring_testcase.not_strongly_equals_minus_one = function(str, subStr) { - const strA = 'abc'; - const foundA = strA.indexOf('b') !== -1; - - const foundB = 'xyz'.indexOf('x') !== -1; - - return str.indexOf(subStr) !== -1; -}; - -/** - * @param {string} str The string. - * @param {string} subStr The sub-string to check. - * @return {boolean} Whether the sub-string is found the string. - */ -refactoring_testcase.greater_than_minus_one = function(str, subStr) { - const strA = 'abc'; - const foundA = strA.indexOf('b') > -1; - - const foundB = 'xyz'.indexOf('x') > -1; - - return str.indexOf(subStr) > -1; -}; - -/** - * @param {string} str The string. - * @param {string} subStr The sub-string to check. - * @return {boolean} Whether the sub-string is found the string. - */ -refactoring_testcase.greater_than_or_equals_zero = function(str, subStr) { - const strA = 'abc'; - const foundA = strA.indexOf('b') >= 0; - - const foundB = 'xyz'.indexOf('x') >= 0; - - return str.indexOf(subStr) >= 0; -}; - -/** - * @param {string} str The string. - * @param {string} subStr The sub-string to check. - * @return {boolean} Whether the sub-string is found the string. - */ -refactoring_testcase.equals_minus_one = function(str, subStr) { - const strA = 'abc'; - const foundA = strA.indexOf('b') == -1; - - const foundB = 'xyz'.indexOf('x') == -1; - - return str.indexOf(subStr) == -1; -}; - -/** - * @param {string} str The string. - * @param {string} subStr The sub-string to check. - * @return {boolean} Whether the sub-string is found the string. - */ -refactoring_testcase.strongly_equals_minus_one = function(str, subStr) { - const strA = 'abc'; - const foundA = strA.indexOf('b') === -1; - - const foundB = 'xyz'.indexOf('x') === -1; - - return str.indexOf(subStr) === -1; -}; - -/** - * @param {string} str The string. - * @param {string} subStr The sub-string to check. - * @return {boolean} Whether the sub-string is found the string. - */ -refactoring_testcase.less_than_zero = function(str, subStr) { - const strA = 'abc'; - const foundA = strA.indexOf('b') < 0; - - const foundB = 'xyz'.indexOf('x') < 0; - - return str.indexOf(subStr) < 0; -}; - -/** - * @param {string} str The string. - * @param {string} subStr The sub-string to check. - * @return {number|boolean} Whether the sub-string is found the string. - * Returns true/truthy if the value is found, false/falsy otherwise. - */ -refactoring_testcase.bitwise_not = function(str, subStr) { - const strA = 'abc'; - const foundA = ~strA.indexOf('b'); - - const foundB = ~'xyz'.indexOf('x'); - - return ~str.indexOf(subStr); -}; - -/** - * The refactoring should ignore calls to indexOf on non-array objects. - * @param {string} str A string. - * @param {string} subStr The substring to check. - * @return {boolean} Whether the substring is in the array. - */ -refactoring_testcase.ignore_non_strings = function(str, subStr) { - // Array.prototype.indexOf. - const arrA = ['a', 'b', 'c']; - arrA.indexOf('z'); - const indexOfZ = ['x', 'y', 'z'].indexOf('z') == 2; - - // method in object. - const objA = {indexOf: function(a) {}}; - objA.indexOf(''); - - // shorthand method names. - const objB = {indexOf(a) {}}; - objB.indexOf(''); - - return str.indexOf(subStr) != -1; -}; diff --git a/test/com/google/javascript/refactoring/examples/testdata/string_indexof_to_includes_out.js b/test/com/google/javascript/refactoring/examples/testdata/string_indexof_to_includes_out.js deleted file mode 100644 index 1d810aeb364..00000000000 --- a/test/com/google/javascript/refactoring/examples/testdata/string_indexof_to_includes_out.js +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright 2017 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. - */ - -/** - * @fileoverview Test cases for string_indexof_to_includes RefasterJs template. - * @suppress {unusedLocalVariables} - */ - -goog.provide('refactoring_testcase'); - - -/** - * @param {string} str The string. - * @param {string} subStr The sub-string to check. - * @return {boolean} Whether the sub-string is found the string. - */ -refactoring_testcase.not_equals_minus_one = function(str, subStr) { - const strA = 'abc'; - const foundA = strA.includes('b'); - - const foundB = 'xyz'.includes('x'); - - return str.includes(subStr); -}; - -/** - * @param {string} str The string. - * @param {string} subStr The sub-string to check. - * @return {boolean} Whether the sub-string is found the string. - */ -refactoring_testcase.not_strongly_equals_minus_one = function(str, subStr) { - const strA = 'abc'; - const foundA = strA.includes('b'); - - const foundB = 'xyz'.includes('x'); - - return str.includes(subStr); -}; - -/** - * @param {string} str The string. - * @param {string} subStr The sub-string to check. - * @return {boolean} Whether the sub-string is found the string. - */ -refactoring_testcase.greater_than_minus_one = function(str, subStr) { - const strA = 'abc'; - const foundA = strA.includes('b'); - - const foundB = 'xyz'.includes('x'); - - return str.includes(subStr); -}; - -/** - * @param {string} str The string. - * @param {string} subStr The sub-string to check. - * @return {boolean} Whether the sub-string is found the string. - */ -refactoring_testcase.greater_than_or_equals_zero = function(str, subStr) { - const strA = 'abc'; - const foundA = strA.includes('b'); - - const foundB = 'xyz'.includes('x'); - - return str.includes(subStr); -}; - -/** - * @param {string} str The string. - * @param {string} subStr The sub-string to check. - * @return {boolean} Whether the sub-string is found the string. - */ -refactoring_testcase.equals_minus_one = function(str, subStr) { - const strA = 'abc'; - const foundA = !strA.includes('b'); - - const foundB = !'xyz'.includes('x'); - - return !str.includes(subStr); -}; - -/** - * @param {string} str The string. - * @param {string} subStr The sub-string to check. - * @return {boolean} Whether the sub-string is found the string. - */ -refactoring_testcase.strongly_equals_minus_one = function(str, subStr) { - const strA = 'abc'; - const foundA = !strA.includes('b'); - - const foundB = !'xyz'.includes('x'); - - return !str.includes(subStr); -}; - -/** - * @param {string} str The string. - * @param {string} subStr The sub-string to check. - * @return {boolean} Whether the sub-string is found the string. - */ -refactoring_testcase.less_than_zero = function(str, subStr) { - const strA = 'abc'; - const foundA = !strA.includes('b'); - - const foundB = !'xyz'.includes('x'); - - return !str.includes(subStr); -}; - -/** - * @param {string} str The string. - * @param {string} subStr The sub-string to check. - * @return {number|boolean} Whether the sub-string is found the string. - * Returns true/truthy if the value is found, false/falsy otherwise. - */ -refactoring_testcase.bitwise_not = function(str, subStr) { - const strA = 'abc'; - const foundA = strA.includes('b'); - - const foundB = 'xyz'.includes('x'); - - return str.includes(subStr); -}; - -/** - * The refactoring should ignore calls to indexOf on non-array objects. - * @param {string} str A string. - * @param {string} subStr The substring to check. - * @return {boolean} Whether the substring is in the array. - */ -refactoring_testcase.ignore_non_strings = function(str, subStr) { - // Array.prototype.indexOf. - const arrA = ['a', 'b', 'c']; - arrA.indexOf('z'); - const indexOfZ = ['x', 'y', 'z'].indexOf('z') == 2; - - // method in object. - const objA = {indexOf: function(a) {}}; - objA.indexOf(''); - - // shorthand method names. - const objB = {indexOf(a) {}}; - objB.indexOf(''); - - return str.includes(subStr); -};