diff --git a/src/main/java/com/cflint/CFLint.java b/src/main/java/com/cflint/CFLint.java
index b6956d325..ec4b4d2e0 100644
--- a/src/main/java/com/cflint/CFLint.java
+++ b/src/main/java/com/cflint/CFLint.java
@@ -425,12 +425,19 @@ public String stripLineComments(final String cfscript) {
private void process(final CFScriptStatement expression, final String filename, final Element elem,
final CFIdentifier functionName) {
- process(expression,filename,elem,functionName.Decompile(0));
+ process(expression,filename,elem,functionName.getName());
}
private void process(final CFScriptStatement expression, final String filename, final Element elem,
- final String functionName) {
+ String functionName) {
final Context context = new Context(filename, elem, functionName, inAssignment, handler);
+
context.setInComponent(inComponent);
+
+ if (expression instanceof CFFuncDeclStatement) {
+ final CFFuncDeclStatement function = (CFFuncDeclStatement) expression;
+ functionName = function.getName().getName();
+ context.setFunctionName(functionName);
+ }
for (final CFLintScanner plugin : extensions) {
try{
diff --git a/src/main/java/com/cflint/plugins/Context.java b/src/main/java/com/cflint/plugins/Context.java
index 4ff4fac35..358f6783e 100644
--- a/src/main/java/com/cflint/plugins/Context.java
+++ b/src/main/java/com/cflint/plugins/Context.java
@@ -147,7 +147,7 @@ public int startLine() {
if(element != null && element.getSource() !=null)
return element.getSource().getRow(element.getBegin());
else
- return 1;
+ return 1; // not zero
}
protected String componentFromFile(String filename) {
diff --git a/src/main/java/com/cflint/plugins/core/MethodNameChecker.java b/src/main/java/com/cflint/plugins/core/MethodNameChecker.java
new file mode 100644
index 000000000..ef1a88fe4
--- /dev/null
+++ b/src/main/java/com/cflint/plugins/core/MethodNameChecker.java
@@ -0,0 +1,106 @@
+package com.cflint.plugins.core;
+
+import ro.fortsoft.pf4j.Extension;
+import net.htmlparser.jericho.Element;
+import net.htmlparser.jericho.Attributes;
+import cfml.parsing.cfscript.script.CFScriptStatement;
+import cfml.parsing.cfscript.script.CFFuncDeclStatement;
+
+
+import com.cflint.BugInfo;
+import com.cflint.BugList;
+import com.cflint.plugins.CFLintScannerAdapter;
+import com.cflint.plugins.Context;
+
+import java.util.regex.Pattern;
+
+@Extension
+public class MethodNameChecker extends CFLintScannerAdapter {
+ final String severity = "INFO";
+
+ @Override
+ public void expression(final CFScriptStatement expression, final Context context, final BugList bugs) {
+ if (expression instanceof CFFuncDeclStatement) {
+ final CFFuncDeclStatement method = (CFFuncDeclStatement) expression;
+ int lineNo = method.getLine() + context.startLine() - 1;
+ checkNameForBugs(context.getFunctionName(), context.getFilename(), lineNo, bugs);
+ }
+ }
+
+ @Override
+ public void element(final Element element, final Context context, final BugList bugs) {
+ if (element.getName().equals("cffunction")) {
+ int lineNo = element.getSource().getRow(element.getBegin());
+ checkNameForBugs(context.getFunctionName(), context.getFilename(), lineNo, bugs);
+ }
+ }
+
+ public void checkNameForBugs(String method, String filename, int line, BugList bugs) {
+ int minMethodLength = ValidName.MIN_METHOD_LENGTH;
+ int maxMethodLength = ValidName.MAX_METHOD_LENGTH;
+ int maxMethodWords = ValidName.MAX_METHOD_WORDS;
+
+ if (getParameter("MinLength") != null) {
+ try {
+ minMethodLength = Integer.parseInt(getParameter("MinLength"));
+ } catch(Exception e) {}
+ }
+
+ if (getParameter("MaxLength") != null) {
+ try {
+ maxMethodLength = Integer.parseInt(getParameter("MaxLength"));
+ } catch(Exception e) {}
+ }
+
+ if (getParameter("MaxWords") != null) {
+ try {
+ maxMethodWords = Integer.parseInt(getParameter("MaxWords"));
+ } catch(Exception e) {}
+ }
+
+ ValidName name = new ValidName(minMethodLength, maxMethodLength, maxMethodWords);
+
+ if (name.isInvalid(method)) {
+ bugs.add(new BugInfo.BugInfoBuilder().setLine(line).setMessageCode("METHOD_INVALID_NAME")
+ .setSeverity(severity).setFilename(filename)
+ .setMessage("Method name " + method + " is not a valid name. Please use CamelCase or underscores.")
+ .build());
+ }
+ if (name.isUpperCase(method)) {
+ bugs.add(new BugInfo.BugInfoBuilder().setLine(line).setMessageCode("METHOD_ALLCAPS_NAME")
+ .setSeverity(severity).setFilename(filename)
+ .setMessage("Method name " + method + " should not be upper case.")
+ .build());
+ }
+ if (name.tooShort(method)) {
+ bugs.add(new BugInfo.BugInfoBuilder().setLine(line).setMessageCode("METHOD_TOO_SHORT")
+ .setSeverity(severity).setFilename(filename)
+ .setMessage("Method name " + method + " should be longer than " + minMethodLength + " characters.")
+ .build());
+ }
+ if (name.tooLong(method)) {
+ bugs.add(new BugInfo.BugInfoBuilder().setLine(line).setMessageCode("METHOD_TOO_LONG")
+ .setSeverity(severity).setFilename(filename)
+ .setMessage("Method name " + method + " should be shorter than " + maxMethodLength + " characters.")
+ .build());
+ }
+ if (!name.isUpperCase(method) && name.tooWordy(method)) {
+ bugs.add(new BugInfo.BugInfoBuilder().setLine(line).setMessageCode("METHOD_TOO_WORDY")
+ .setSeverity(severity).setFilename(filename)
+ .setMessage("Method name " + method + " is too wordy, can you think of a more concise name?")
+ .build());
+ }
+ if (name.isTemporary(method)) {
+ bugs.add(new BugInfo.BugInfoBuilder().setLine(line).setMessageCode("METHOD_IS_TEMPORARY")
+ .setSeverity(severity).setFilename(filename)
+ .setMessage("Method name " + method + " could be named better.")
+ .build());
+ }
+ if (name.hasPrefixOrPostfix(method)) {
+ bugs.add(new BugInfo.BugInfoBuilder().setLine(line).setMessageCode("METHOD_HAS_PREFIX_OR_POSTFIX")
+ .setSeverity(severity).setFilename(filename)
+ .setMessage("Method name has prefix or postfix " + method + " and could be named better.")
+ .build());
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/cflint/plugins/core/ValidName.java b/src/main/java/com/cflint/plugins/core/ValidName.java
new file mode 100644
index 000000000..1c8aa63f0
--- /dev/null
+++ b/src/main/java/com/cflint/plugins/core/ValidName.java
@@ -0,0 +1,132 @@
+
+package com.cflint.plugins.core;
+
+import java.util.regex.Pattern;
+
+public class ValidName {
+ public static final int MIN_VAR_LENGTH = 3;
+ public static final int MAX_VAR_LENGTH = 20;
+ public static final int MAX_VAR_WORDS = 4;
+
+ public static final int MIN_METHOD_LENGTH = 3;
+ public static final int MAX_METHOD_LENGTH = 25;
+ public static final int MAX_METHOD_WORDS = 5;
+
+ protected int minLength = MIN_VAR_LENGTH;
+ protected int maxLength = MAX_VAR_LENGTH;
+ protected int maxWords = MAX_VAR_WORDS;
+
+ public ValidName() {
+ }
+
+ public ValidName(int minLength, int maxLength, int maxWords) {
+ this.minLength = minLength;
+ this.maxLength = maxLength;
+ this.maxWords = maxWords;
+ }
+
+ public boolean isInvalid(String name) {
+ return !validChars(name) || endsInNumber(name) || !(isSameCase(name) || isCamelCaseLower(name) || usesUnderscores(name));
+ }
+
+ public boolean validChars(String name) {
+ Pattern valid = Pattern.compile("^[A-Za-z0-9_]+$");
+ return valid.matcher(name).matches();
+ }
+
+ public boolean isUpperCase(String name) {
+ return name.toUpperCase().equals(name);
+ }
+
+ public boolean isSameCase(String name) {
+ return name.equals(name.toLowerCase()) || name.equals(name.toUpperCase());
+ }
+
+ public boolean isCamelCaseLower(String name) {
+ // [A-Z0-9]{2,5} catch names like productID, phone4G, requestURL etc etc
+ Pattern valid = Pattern.compile("^[a-z0-9]+([A-Z]{1,5}[a-z0-9]+)*([A-Z0-9]{2,5}){0,1}$");
+ return valid.matcher(name).matches();
+ }
+
+ public boolean isCamelCaseUpper(String name) {
+ Pattern valid = Pattern.compile("^([A-Z]{1,5}[a-z0-9]+)+([A-Z0-9]{2,5}){0,1}$");
+ return valid.matcher(name).matches();
+ }
+
+ public boolean usesUnderscores(String name) {
+ return name.indexOf('_') != -1;
+ }
+
+ public boolean endsInNumber(String name) {
+ char lastLetter = name.charAt(name.length() - 1);
+
+ if (Character.isDigit(lastLetter)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ public boolean tooShort(String name) {
+ return name.length() < minLength;
+ }
+
+ public boolean tooLong(String name) {
+ return name.length() > maxLength;
+ }
+
+ public boolean tooWordy(String name) {
+ String[] words = name.split("[A-Z_]+");
+ int count = 0;
+
+ for (int i = 0; i < words.length; i++) {
+ if (words[i] != null && !words[i].equals("")) {
+ count++;
+ }
+ }
+
+ return count > maxWords;
+ }
+
+ public boolean isTemporary(String name) {
+ String[] wordsToAvoid = {"temp", "tmp", "var", "func", "obj", "object", "bool", "struct", "string", "array", "comp"};
+ String sentence = name.replaceAll("_", " ");
+ sentence = sentence.replaceAll("(\\p{Ll})(\\p{Lu})","$1 $2");
+ String[] words = sentence.split(" ");
+
+ for (String badWord : wordsToAvoid) {
+ for (String word : words) {
+ if (word.toLowerCase().equals(badWord))
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ public boolean hasPrefixOrPostfix(String name) {
+ String[] namesToAvoid = {"s", "st", "str", "o", "obj", "b", "q", "a", "arr", "this", "my"};
+ String sentence = name.replaceAll("_", " ");
+ sentence = sentence.replaceAll("(\\p{Ll})(\\p{Lu})","$1 $2");
+ String[] words = sentence.split(" ");
+ String firstWord = words[0];
+ String lastWord = words[words.length-1];
+
+ if (words.length > 1) {
+ for (String badName : namesToAvoid) {
+ if (firstWord.toLowerCase().equals(badName))
+ {
+ return true;
+ }
+ if (lastWord.toLowerCase().equals(badName))
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/cflint/plugins/core/VariableNameChecker.java b/src/main/java/com/cflint/plugins/core/VariableNameChecker.java
new file mode 100644
index 000000000..552f2b99a
--- /dev/null
+++ b/src/main/java/com/cflint/plugins/core/VariableNameChecker.java
@@ -0,0 +1,111 @@
+package com.cflint.plugins.core;
+
+import ro.fortsoft.pf4j.Extension;
+import net.htmlparser.jericho.Element;
+import net.htmlparser.jericho.Attributes;
+import cfml.parsing.cfscript.CFAssignmentExpression;
+import cfml.parsing.cfscript.CFExpression;
+import cfml.parsing.cfscript.CFFullVarExpression;
+import cfml.parsing.cfscript.CFIdentifier;
+import cfml.parsing.cfscript.CFVarDeclExpression;
+
+import com.cflint.BugInfo;
+import com.cflint.BugList;
+import com.cflint.plugins.CFLintScannerAdapter;
+import com.cflint.plugins.Context;
+
+import java.util.regex.Pattern;
+
+@Extension
+public class VariableNameChecker extends CFLintScannerAdapter {
+ final String severity = "INFO";
+
+ public void expression(final CFExpression expression, final Context context, final BugList bugs) {
+ if (expression instanceof CFVarDeclExpression) {
+ final CFVarDeclExpression cfVarDeclExpression = (CFVarDeclExpression)expression;
+ int lineNo = expression.getLine() + context.startLine() - 1;
+ checkNameForBugs(cfVarDeclExpression.getName(), context.getFilename(), lineNo, bugs);
+ }
+ else if (expression instanceof CFFullVarExpression) {
+ final CFFullVarExpression cfFullVarExpression = (CFFullVarExpression)expression;
+ for(final CFExpression subexpression : cfFullVarExpression.getExpressions()){
+ expression(subexpression,context,bugs);
+ }
+ }
+ else if (expression instanceof CFIdentifier) {
+ String varName = ((CFIdentifier) expression).getName();
+ int lineNo = ((CFIdentifier) expression).getLine() + context.startLine() - 1;
+
+ checkNameForBugs(varName, context.getFilename(), lineNo, bugs);
+ }
+ }
+
+ public void checkNameForBugs(String variable, String filename, int line, BugList bugs) {
+ int minVarLength = ValidName.MIN_VAR_LENGTH;
+ int maxVarLength = ValidName.MAX_VAR_LENGTH;
+ int maxVarWords = ValidName.MAX_VAR_WORDS;
+
+ if (getParameter("MinLength") != null) {
+ try {
+ minVarLength = Integer.parseInt(getParameter("MinLength"));
+ } catch(Exception e) {}
+ }
+
+ if (getParameter("MaxLength") != null) {
+ try {
+ maxVarLength = Integer.parseInt(getParameter("MaxLength"));
+ } catch(Exception e) {}
+ }
+
+ if (getParameter("MaxWords") != null) {
+ try {
+ maxVarWords = Integer.parseInt(getParameter("MaxWords"));
+ } catch(Exception e) {}
+ }
+
+ ValidName name = new ValidName(minVarLength, maxVarLength, maxVarWords);
+
+ if (name.isInvalid(variable)) {
+ bugs.add(new BugInfo.BugInfoBuilder().setLine(line).setMessageCode("VAR_INVALID_NAME")
+ .setSeverity(severity).setFilename(filename)
+ .setMessage("Variable " + variable + " is not a valid name. Please use CamelCase or underscores.")
+ .build());
+ }
+ if (name.isUpperCase(variable)) {
+ bugs.add(new BugInfo.BugInfoBuilder().setLine(line).setMessageCode("VAR_ALLCAPS_NAME")
+ .setSeverity(severity).setFilename(filename)
+ .setMessage("Variable " + variable + " should not be upper case.")
+ .build());
+ }
+ if (name.tooShort(variable)) {
+ bugs.add(new BugInfo.BugInfoBuilder().setLine(line).setMessageCode("VAR_TOO_SHORT")
+ .setSeverity(severity).setFilename(filename)
+ .setMessage("Variable " + variable + " should be longer than " + minVarLength + " characters.")
+ .build());
+ }
+ if (name.tooLong(variable)) {
+ bugs.add(new BugInfo.BugInfoBuilder().setLine(line).setMessageCode("VAR_TOO_LONG")
+ .setSeverity(severity).setFilename(filename)
+ .setMessage("Variable " + variable + " should be shorter than " + maxVarLength + " characters.")
+ .build());
+ }
+ if (!name.isUpperCase(variable) && name.tooWordy(variable)) {
+ bugs.add(new BugInfo.BugInfoBuilder().setLine(line).setMessageCode("VAR_TOO_WORDY")
+ .setSeverity(severity).setFilename(filename)
+ .setMessage("Variable " + variable + " is too wordy, can you think of a more concise name?")
+ .build());
+ }
+ if (name.isTemporary(variable)) {
+ bugs.add(new BugInfo.BugInfoBuilder().setLine(line).setMessageCode("VAR_IS_TEMPORARY")
+ .setSeverity(severity).setFilename(filename)
+ .setMessage("Temporary variable " + variable + " could be named better.")
+ .build());
+ }
+ if (name.hasPrefixOrPostfix(variable)) {
+ bugs.add(new BugInfo.BugInfoBuilder().setLine(line).setMessageCode("VAR_HAS_PREFIX_OR_POSTFIX")
+ .setSeverity(severity).setFilename(filename)
+ .setMessage("Variable has prefix or postfix " + variable + " and could be named better.")
+ .build());
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/resources/cflint.definition.json b/src/main/resources/cflint.definition.json
index 572e96894..eb44e8d5d 100644
--- a/src/main/resources/cflint.definition.json
+++ b/src/main/resources/cflint.definition.json
@@ -449,6 +449,102 @@
}
],
"parameter": []
+ },
+ {
+ "name": "VariableNameChecker",
+ "className": "VariableNameChecker",
+ "message": [
+ {
+ "code": "VAR_INVALID_NAME",
+ "severity": "INFO"
+ },
+ {
+ "code": "VAR_ALLCAPS_NAME",
+ "severity": "INFO"
+ },
+ {
+ "code": "VAR_TOO_SHORT",
+ "severity": "INFO"
+ },
+ {
+ "code": "VAR_TOO_LONG",
+ "severity": "INFO"
+ },
+ {
+ "code": "VAR_TOO_WORDY",
+ "severity": "INFO"
+ },
+ {
+ "code": "VAR_IS_TEMPORARY",
+ "severity": "INFO"
+ },
+ {
+ "code": "VAR_HAS_PREFIX_OR_POSTFIX",
+ "severity": "INFO"
+ }
+ ],
+ "parameter": [
+ {
+ "name": "MinLength",
+ "value": "3"
+ },
+ {
+ "name": "MaxLength",
+ "value": "20"
+ },
+ {
+ "name": "MaxWords",
+ "value": "4"
+ }
+ ]
+ },
+ {
+ "name": "MethodNameChecker",
+ "className": "MethodNameChecker",
+ "message": [
+ {
+ "code": "METHOD_INVALID_NAME",
+ "severity": "INFO"
+ },
+ {
+ "code": "METHOD_ALLCAPS_NAME",
+ "severity": "INFO"
+ },
+ {
+ "code": "METHOD_TOO_SHORT",
+ "severity": "INFO"
+ },
+ {
+ "code": "METHOD_TOO_LONG",
+ "severity": "INFO"
+ },
+ {
+ "code": "METHOD_TOO_WORDY",
+ "severity": "INFO"
+ },
+ {
+ "code": "METHOD_IS_TEMPORARY",
+ "severity": "INFO"
+ },
+ {
+ "code": "METHOD_HAS_PREFIX_OR_POSTFIX",
+ "severity": "INFO"
+ }
+ ],
+ "parameter": [
+ {
+ "name": "MinLength",
+ "value": "3"
+ },
+ {
+ "name": "MaxLength",
+ "value": "25"
+ },
+ {
+ "name": "MaxWords",
+ "value": "5"
+ }
+ ]
}
]
}
\ No newline at end of file
diff --git a/src/main/resources/cflint.definition.xml b/src/main/resources/cflint.definition.xml
index ed9ad5f6a..2620ca36c 100644
--- a/src/main/resources/cflint.definition.xml
+++ b/src/main/resources/cflint.definition.xml
@@ -211,4 +211,50 @@
WARNING
+
+
+ INFO
+
+
+ INFO
+
+
+ INFO
+
+
+ INFO
+
+
+ INFO
+
+
+ INFO
+
+
+ INFO
+
+
+
+
+ INFO
+
+
+ INFO
+
+
+ INFO
+
+
+ INFO
+
+
+ INFO
+
+
+ INFO
+
+
+ INFO
+
+
diff --git a/src/test/java/com/cflint/TestCFBugs_MethodNames.java b/src/test/java/com/cflint/TestCFBugs_MethodNames.java
new file mode 100644
index 000000000..664b7bf04
--- /dev/null
+++ b/src/test/java/com/cflint/TestCFBugs_MethodNames.java
@@ -0,0 +1,290 @@
+package com.cflint;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import cfml.parsing.reporting.ParseException;
+
+import com.cflint.config.CFLintPluginInfo.PluginInfoRule;
+import com.cflint.config.CFLintPluginInfo.PluginInfoRule.PluginMessage;
+import com.cflint.config.ConfigRuntime;
+import com.cflint.plugins.core.MethodNameChecker;
+
+public class TestCFBugs_MethodNames {
+
+ private CFLint cfBugs;
+
+ @Before
+ public void setUp() {
+ final ConfigRuntime conf = new ConfigRuntime();
+ final PluginInfoRule pluginRule = new PluginInfoRule();
+ pluginRule.setName("MethodNameChecker");
+ conf.getRules().add(pluginRule);
+ PluginMessage pluginMessage = new PluginMessage("METHOD_INVALID_NAME");
+ pluginMessage.setSeverity("INFO");
+ pluginRule.getMessages().add(pluginMessage);
+ pluginMessage = new PluginMessage("METHOD_ALLCAPS_NAME");
+ pluginMessage.setSeverity("INFO");
+ pluginRule.getMessages().add(pluginMessage);
+ pluginMessage = new PluginMessage("METHOD_TOO_SHORT");
+ pluginMessage.setSeverity("INFO");
+ pluginRule.getMessages().add(pluginMessage);
+ pluginRule.addParameter("MinLength", "3");
+ pluginRule.addParameter("MaxLength", "20");
+ pluginMessage = new PluginMessage("METHOD_TOO_LONG");
+ pluginMessage.setSeverity("INFO");
+ pluginRule.getMessages().add(pluginMessage);
+ pluginMessage = new PluginMessage("METHOD_TOO_WORDY");
+ pluginMessage.setSeverity("INFO");
+ pluginRule.getMessages().add(pluginMessage);
+ pluginRule.addParameter("MaxWords", "4");
+ pluginMessage = new PluginMessage("METHOD_IS_TEMPORARY");
+ pluginMessage.setSeverity("INFO");
+ pluginRule.getMessages().add(pluginMessage);
+ pluginMessage = new PluginMessage("METHOD_HAS_PREFIX_OR_POSTFIX");
+ pluginMessage.setSeverity("INFO");
+ pluginRule.getMessages().add(pluginMessage);
+
+ final MethodNameChecker checker = new MethodNameChecker();
+ cfBugs = new CFLint(conf, checker);
+ }
+
+ @Test
+ public void testValidNamesTag() throws ParseException, IOException {
+ final String tagSrc = "\r\n"
+ + "\r\n"
+ + "\r\n"
+ + "";
+ cfBugs.process(tagSrc, "test");
+ Collection> result = cfBugs.getBugs().getBugList().values();
+ assertEquals(0, result.size());
+ }
+
+ @Test
+ public void testUpercaseNameTag() throws ParseException, IOException {
+ final String tagSrc = "\r\n"
+ + "\r\n"
+ + "\r\n"
+ + "";
+ cfBugs.process(tagSrc, "test");
+ final List result = cfBugs.getBugs().getBugList().values().iterator().next();
+ assertEquals(1, result.size());
+ assertEquals("METHOD_ALLCAPS_NAME", result.get(0).getMessageCode());
+ assertEquals(2, result.get(0).getLine());
+ }
+
+ @Test
+ public void invalidCharsInNameTag() throws ParseException, IOException {
+ final String tagSrc = "\r\n"
+ + "\r\n"
+ + "\r\n"
+ + "";
+ cfBugs.process(tagSrc, "test");
+ final List result = cfBugs.getBugs().getBugList().values().iterator().next();
+ assertEquals(1, result.size());
+ assertEquals("METHOD_INVALID_NAME", result.get(0).getMessageCode());
+ assertEquals(2, result.get(0).getLine());
+ }
+
+ @Test
+ public void nameEndsInNumberTag() throws ParseException, IOException {
+ final String tagSrc = "\r\n"
+ + "\r\n"
+ + "\r\n"
+ + "";
+ cfBugs.process(tagSrc, "test");
+ final List result = cfBugs.getBugs().getBugList().values().iterator().next();
+ assertEquals(1, result.size());
+ assertEquals("METHOD_INVALID_NAME", result.get(0).getMessageCode());
+ assertEquals(2, result.get(0).getLine());
+ }
+
+ @Test
+ public void nameTooShortTag() throws ParseException, IOException {
+ final String tagSrc = "\r\n"
+ + "\r\n"
+ + "\r\n"
+ + "";
+ cfBugs.process(tagSrc, "test");
+ final List result = cfBugs.getBugs().getBugList().values().iterator().next();
+ assertEquals(1, result.size());
+ assertEquals("METHOD_TOO_SHORT", result.get(0).getMessageCode());
+ assertEquals(2, result.get(0).getLine());
+ }
+
+ @Test
+ public void nameTooLongTag() throws ParseException, IOException {
+ final String tagSrc = "\r\n"
+ + "\r\n"
+ + "\r\n"
+ + "";
+ cfBugs.process(tagSrc, "test");
+ final List result = cfBugs.getBugs().getBugList().values().iterator().next();
+ assertEquals(1, result.size());
+ assertEquals("METHOD_TOO_LONG", result.get(0).getMessageCode());
+ assertEquals(2, result.get(0).getLine());
+ }
+
+ @Test
+ public void nameTooWordyTag() throws ParseException, IOException {
+ final String tagSrc = "\r\n"
+ + "\r\n"
+ + "\r\n"
+ + "";
+ cfBugs.process(tagSrc, "test");
+ final List result = cfBugs.getBugs().getBugList().values().iterator().next();
+ assertEquals(1, result.size());
+ assertEquals("METHOD_TOO_WORDY", result.get(0).getMessageCode());
+ assertEquals(2, result.get(0).getLine());
+ }
+
+ @Test
+ public void nameIsTemporyTag() throws ParseException, IOException {
+ final String tagSrc = "\r\n"
+ + "\r\n"
+ + "\r\n"
+ + "";
+ cfBugs.process(tagSrc, "test");
+ final List result = cfBugs.getBugs().getBugList().get("METHOD_IS_TEMPORARY");
+ assertEquals(1, result.size());
+ assertEquals("METHOD_IS_TEMPORARY", result.get(0).getMessageCode());
+ assertEquals(2, result.get(0).getLine());
+ }
+
+ @Test
+ public void nameHasPrefixOrPostfixTag() throws ParseException, IOException {
+ final String tagSrc = "\r\n"
+ + "\r\n"
+ + "\r\n"
+ + "";
+ cfBugs.process(tagSrc, "test");
+ final List result = cfBugs.getBugs().getBugList().values().iterator().next();
+ assertEquals(1, result.size());
+ assertEquals("METHOD_HAS_PREFIX_OR_POSTFIX", result.get(0).getMessageCode());
+ assertEquals(2, result.get(0).getLine());
+ }
+
+
+ @Test
+ public void testValidNamesScript() throws ParseException, IOException {
+ final String scriptSrc = "component {\r\n"
+ + "function test() {\r\n"
+ + "}\r\n"
+ + "}";
+ cfBugs.process(scriptSrc, "test");
+ Collection> result = cfBugs.getBugs().getBugList().values();
+ assertEquals(0, result.size());
+ }
+
+ @Test
+ public void testUpercaseNameScript() throws ParseException, IOException {
+ final String scriptSrc = "component {\r\n"
+ + "function UPPERCASE() {\r\n"
+ + "}\r\n"
+ + "}";
+ cfBugs.process(scriptSrc, "test");
+ final List result = cfBugs.getBugs().getBugList().values().iterator().next();
+ assertEquals(1, result.size());
+ assertEquals("METHOD_ALLCAPS_NAME", result.get(0).getMessageCode());
+ assertEquals(2, result.get(0).getLine());
+ }
+
+ @Test
+ public void invalidCharsInNameScript() throws ParseException, IOException {
+ final String scriptSrc = "component {\r\n"
+ + "function method$name() {\r\n"
+ + "}\r\n"
+ + "}";
+ cfBugs.process(scriptSrc, "test");
+ final List result = cfBugs.getBugs().getBugList().values().iterator().next();
+ assertEquals(1, result.size());
+ assertEquals("METHOD_INVALID_NAME", result.get(0).getMessageCode());
+ assertEquals(2, result.get(0).getLine());
+ }
+
+ @Test
+ public void nameEndsInNumberScript() throws ParseException, IOException {
+ final String scriptSrc = "component {\r\n"
+ + "function method23() {\r\n"
+ + "}\r\n"
+ + "}";
+ cfBugs.process(scriptSrc, "test");
+ final List result = cfBugs.getBugs().getBugList().values().iterator().next();
+ assertEquals(1, result.size());
+ assertEquals("METHOD_INVALID_NAME", result.get(0).getMessageCode());
+ assertEquals(2, result.get(0).getLine());
+ }
+
+ @Test
+ public void nameTooShortScript() throws ParseException, IOException {
+ final String scriptSrc = "component {\r\n"
+ + "function a() {\r\n"
+ + "}\r\n"
+ + "}";
+ cfBugs.process(scriptSrc, "test");
+ final List result = cfBugs.getBugs().getBugList().values().iterator().next();
+ assertEquals(1, result.size());
+ assertEquals("METHOD_TOO_SHORT", result.get(0).getMessageCode());
+ assertEquals(2, result.get(0).getLine());
+ }
+
+ @Test
+ public void nameTooLongScript() throws ParseException, IOException {
+ final String scriptSrc = "component {\r\n"
+ + "function isaveryveryverylongmethodname() {\r\n"
+ + "}\r\n"
+ + "}";
+ cfBugs.process(scriptSrc, "test");
+ final List result = cfBugs.getBugs().getBugList().values().iterator().next();
+ assertEquals(1, result.size());
+ assertEquals("METHOD_TOO_LONG", result.get(0).getMessageCode());
+ assertEquals(2, result.get(0).getLine());
+ }
+
+ @Test
+ public void nameTooWordyScript() throws ParseException, IOException {
+ final String scriptSrc = "component {\r\n"
+ + "function isFarTooWordyMethodName() {\r\n"
+ + "}\r\n"
+ + "}";
+ cfBugs.process(scriptSrc, "test");
+ final List result = cfBugs.getBugs().getBugList().values().iterator().next();
+ assertEquals(1, result.size());
+ assertEquals("METHOD_TOO_WORDY", result.get(0).getMessageCode());
+ assertEquals(2, result.get(0).getLine());
+ }
+
+ @Test
+ public void nameIsTemporyScript() throws ParseException, IOException {
+ final String scriptSrc = "component {\r\n"
+ + "function temp() {\r\n"
+ + "}\r\n"
+ + "}";
+ cfBugs.process(scriptSrc, "test");
+ final List result = cfBugs.getBugs().getBugList().get("METHOD_IS_TEMPORARY");
+ assertEquals(1, result.size());
+ assertEquals("METHOD_IS_TEMPORARY", result.get(0).getMessageCode());
+ assertEquals(2, result.get(0).getLine());
+ }
+
+ @Test
+ public void nameHasPrefixOrPostfixScript() throws ParseException, IOException {
+ final String scriptSrc = "component {\r\n"
+ + "function thisMethod() {\r\n"
+ + "}\r\n"
+ + "}";
+ cfBugs.process(scriptSrc, "test");
+ final List result = cfBugs.getBugs().getBugList().values().iterator().next();
+ assertEquals(1, result.size());
+ assertEquals("METHOD_HAS_PREFIX_OR_POSTFIX", result.get(0).getMessageCode());
+ assertEquals(2, result.get(0).getLine());
+ }
+
+}
diff --git a/src/test/java/com/cflint/TestCFBugs_VariableNames.java b/src/test/java/com/cflint/TestCFBugs_VariableNames.java
new file mode 100644
index 000000000..91fadf49a
--- /dev/null
+++ b/src/test/java/com/cflint/TestCFBugs_VariableNames.java
@@ -0,0 +1,460 @@
+package com.cflint;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import cfml.parsing.reporting.ParseException;
+
+import com.cflint.config.CFLintPluginInfo.PluginInfoRule;
+import com.cflint.config.CFLintPluginInfo.PluginInfoRule.PluginMessage;
+import com.cflint.config.ConfigRuntime;
+import com.cflint.plugins.core.VariableNameChecker;
+
+public class TestCFBugs_VariableNames {
+
+ private CFLint cfBugs;
+
+ @Before
+ public void setUp() {
+ final ConfigRuntime conf = new ConfigRuntime();
+ final PluginInfoRule pluginRule = new PluginInfoRule();
+ pluginRule.setName("VariableNameChecker");
+ conf.getRules().add(pluginRule);
+ PluginMessage pluginMessage = new PluginMessage("VAR_INVALID_NAME");
+ pluginMessage.setSeverity("INFO");
+ pluginRule.getMessages().add(pluginMessage);
+ pluginMessage = new PluginMessage("VAR_ALLCAPS_NAME");
+ pluginMessage.setSeverity("INFO");
+ pluginRule.getMessages().add(pluginMessage);
+ pluginMessage = new PluginMessage("VAR_TOO_SHORT");
+ pluginMessage.setSeverity("INFO");
+ pluginRule.getMessages().add(pluginMessage);
+ pluginRule.addParameter("MinLength", "3");
+ pluginRule.addParameter("MaxLength", "20");
+ pluginMessage = new PluginMessage("VAR_TOO_LONG");
+ pluginMessage.setSeverity("INFO");
+ pluginRule.getMessages().add(pluginMessage);
+ pluginMessage = new PluginMessage("VAR_TOO_WORDY");
+ pluginMessage.setSeverity("INFO");
+ pluginRule.getMessages().add(pluginMessage);
+ pluginRule.addParameter("MaxWords", "4");
+ pluginMessage = new PluginMessage("VAR_IS_TEMPORARY");
+ pluginMessage.setSeverity("INFO");
+ pluginRule.getMessages().add(pluginMessage);
+ pluginMessage = new PluginMessage("VAR_HAS_PREFIX_OR_POSTFIX");
+ pluginMessage.setSeverity("INFO");
+ pluginRule.getMessages().add(pluginMessage);
+
+ final VariableNameChecker checker = new VariableNameChecker();
+ cfBugs = new CFLint(conf, checker);
+ }
+
+ @Test
+ public void testValidNamesTag() throws ParseException, IOException {
+ final String tagSrc = "\r\n"
+ + "\r\n"
+ + " \r\n"
+ + " \r\n"
+ + " \r\n"
+ + " \r\n"
+ + " \r\n"
+ + " \r\n"
+ + "\r\n"
+ + "";
+ cfBugs.process(tagSrc, "test");
+ Collection> result = cfBugs.getBugs().getBugList().values();
+ assertEquals(0, result.size());
+ }
+
+ @Test
+ public void testUpercaseNameTag() throws ParseException, IOException {
+ final String tagSrc = "\r\n"
+ + "\r\n"
+ + " \r\n"
+ + " \r\n"
+ + " \r\n"
+ + " \r\n"
+ + " \r\n"
+ + "\r\n"
+ + "";
+ cfBugs.process(tagSrc, "test");
+ final List result = cfBugs.getBugs().getBugList().values().iterator().next();
+ assertEquals(4, result.size());
+ assertEquals("VAR_ALLCAPS_NAME", result.get(0).getMessageCode());
+ assertEquals(3, result.get(0).getLine());
+ assertEquals("VAR_ALLCAPS_NAME", result.get(1).getMessageCode());
+ assertEquals(4, result.get(1).getLine());
+ assertEquals("VAR_ALLCAPS_NAME", result.get(2).getMessageCode());
+ assertEquals(6, result.get(2).getLine());
+ assertEquals("VAR_ALLCAPS_NAME", result.get(3).getMessageCode());
+ assertEquals(7, result.get(3).getLine());
+ }
+
+ @Test
+ public void invalidCharsInNameTag() throws ParseException, IOException {
+ final String tagSrc = "\r\n"
+ + "\r\n"
+ + " \r\n"
+ + " \r\n"
+ + " \r\n"
+ + "\r\n"
+ + "";
+ cfBugs.process(tagSrc, "test");
+ final List result = cfBugs.getBugs().getBugList().values().iterator().next();
+ assertEquals(3, result.size());
+ assertEquals("VAR_INVALID_NAME", result.get(0).getMessageCode());
+ assertEquals(3, result.get(0).getLine());
+ assertEquals("VAR_INVALID_NAME", result.get(1).getMessageCode());
+ assertEquals(4, result.get(1).getLine());
+ assertEquals("VAR_INVALID_NAME", result.get(2).getMessageCode());
+ assertEquals(5, result.get(2).getLine());
+ }
+
+ @Test
+ public void nameEndsInNumberTag() throws ParseException, IOException {
+ final String tagSrc = "\r\n"
+ + "\r\n"
+ + " \r\n"
+ + " \r\n"
+ + " \r\n"
+ + "\r\n"
+ + "";
+ cfBugs.process(tagSrc, "test");
+ final List result = cfBugs.getBugs().getBugList().values().iterator().next();
+ assertEquals(3, result.size());
+ assertEquals("VAR_INVALID_NAME", result.get(0).getMessageCode());
+ assertEquals(3, result.get(0).getLine());
+ assertEquals("VAR_INVALID_NAME", result.get(1).getMessageCode());
+ assertEquals(4, result.get(1).getLine());
+ assertEquals("VAR_INVALID_NAME", result.get(2).getMessageCode());
+ assertEquals(5, result.get(2).getLine());
+ }
+
+ @Test
+ public void nameTooShortTag() throws ParseException, IOException {
+ final String tagSrc = "\r\n"
+ + "\r\n"
+ + " \r\n"
+ + " \r\n"
+ + " \r\n"
+ + "\r\n"
+ + "";
+ cfBugs.process(tagSrc, "test");
+ final List result = cfBugs.getBugs().getBugList().values().iterator().next();
+ assertEquals(3, result.size());
+ assertEquals("VAR_TOO_SHORT", result.get(0).getMessageCode());
+ assertEquals(3, result.get(0).getLine());
+ assertEquals("VAR_TOO_SHORT", result.get(1).getMessageCode());
+ assertEquals(4, result.get(1).getLine());
+ assertEquals("VAR_TOO_SHORT", result.get(2).getMessageCode());
+ assertEquals(5, result.get(2).getLine());
+ }
+
+ @Test
+ public void nameTooLongTag() throws ParseException, IOException {
+ final String tagSrc = "\r\n"
+ + "\r\n"
+ + " \r\n"
+ + " \r\n"
+ + "\r\n"
+ + "";
+ cfBugs.process(tagSrc, "test");
+ final List result = cfBugs.getBugs().getBugList().values().iterator().next();
+ assertEquals(2, result.size());
+ assertEquals("VAR_TOO_LONG", result.get(0).getMessageCode());
+ assertEquals(3, result.get(0).getLine());
+ assertEquals("VAR_TOO_LONG", result.get(1).getMessageCode());
+ assertEquals(4, result.get(1).getLine());
+ }
+
+ @Test
+ public void nameTooWordyTag() throws ParseException, IOException {
+ final String tagSrc = "\r\n"
+ + "\r\n"
+ + " \r\n"
+ + " \r\n"
+ + " \r\n"
+ + "\r\n"
+ + "";
+ cfBugs.process(tagSrc, "test");
+ final List result = cfBugs.getBugs().getBugList().values().iterator().next();
+ assertEquals(2, result.size());
+ assertEquals("VAR_TOO_WORDY", result.get(0).getMessageCode());
+ assertEquals(3, result.get(0).getLine());
+ assertEquals("VAR_TOO_WORDY", result.get(1).getMessageCode());
+ assertEquals(5, result.get(1).getLine());
+ }
+
+ @Test
+ public void nameIsTemporyTag() throws ParseException, IOException {
+ final String tagSrc = "\r\n"
+ + "\r\n"
+ + " \r\n"
+ + " \r\n"
+ + " \r\n"
+ + " \r\n"
+ + " \r\n"
+ + " \r\n"
+ + " \r\n"
+ + "\r\n"
+ + "";
+ cfBugs.process(tagSrc, "test");
+ final List result = cfBugs.getBugs().getBugList().get("VAR_IS_TEMPORARY");
+ assertEquals(7, result.size());
+ assertEquals("VAR_IS_TEMPORARY", result.get(0).getMessageCode());
+ assertEquals(3, result.get(0).getLine());
+ assertEquals("VAR_IS_TEMPORARY", result.get(1).getMessageCode());
+ assertEquals(4, result.get(1).getLine());
+ assertEquals("VAR_IS_TEMPORARY", result.get(2).getMessageCode());
+ assertEquals(5, result.get(2).getLine());
+ assertEquals("VAR_IS_TEMPORARY", result.get(3).getMessageCode());
+ assertEquals(6, result.get(3).getLine());
+ assertEquals("VAR_IS_TEMPORARY", result.get(4).getMessageCode());
+ assertEquals(7, result.get(4).getLine());
+ assertEquals("VAR_IS_TEMPORARY", result.get(5).getMessageCode());
+ assertEquals(8, result.get(5).getLine());
+ assertEquals("VAR_IS_TEMPORARY", result.get(6).getMessageCode());
+ assertEquals(9, result.get(6).getLine());
+ }
+
+ @Test
+ public void nameHasPrefixOrPostfixTag() throws ParseException, IOException {
+ final String tagSrc = "\r\n"
+ + "\r\n"
+ + " \r\n"
+ + " \r\n"
+ + " \r\n"
+ + " \r\n"
+ + " \r\n"
+ + " \r\n"
+ + " \r\n"
+ + "\r\n"
+ + "";
+ cfBugs.process(tagSrc, "test");
+ final List result = cfBugs.getBugs().getBugList().values().iterator().next();
+ assertEquals(7, result.size());
+ assertEquals("VAR_HAS_PREFIX_OR_POSTFIX", result.get(0).getMessageCode());
+ assertEquals(3, result.get(0).getLine());
+ assertEquals("VAR_HAS_PREFIX_OR_POSTFIX", result.get(1).getMessageCode());
+ assertEquals(4, result.get(1).getLine());
+ assertEquals("VAR_HAS_PREFIX_OR_POSTFIX", result.get(2).getMessageCode());
+ assertEquals(5, result.get(2).getLine());
+ assertEquals("VAR_HAS_PREFIX_OR_POSTFIX", result.get(3).getMessageCode());
+ assertEquals(6, result.get(3).getLine());
+ assertEquals("VAR_HAS_PREFIX_OR_POSTFIX", result.get(4).getMessageCode());
+ assertEquals(7, result.get(4).getLine());
+ assertEquals("VAR_HAS_PREFIX_OR_POSTFIX", result.get(5).getMessageCode());
+ assertEquals(8, result.get(5).getLine());
+ assertEquals("VAR_HAS_PREFIX_OR_POSTFIX", result.get(6).getMessageCode());
+ assertEquals(9, result.get(6).getLine());
+ }
+
+
+ @Test
+ public void testValidNamesScript() throws ParseException, IOException {
+ final String scriptSrc = "component {\r\n"
+ + "function test() {\r\n"
+ + " var firstName = \"Fred\";\r\n"
+ + " first_name = \"Fred\";\r\n"
+ + " firstname = \"Fred\";\r\n"
+ + " name.first = \"Fred\";\r\n"
+ + " name.last = \"Smith\";\r\n"
+ + " names[1] = \"Smith\";\r\n"
+ + "}\r\n"
+ + "}";
+ cfBugs.process(scriptSrc, "test");
+ Collection> result = cfBugs.getBugs().getBugList().values();
+ assertEquals(0, result.size());
+ }
+
+ @Test
+ public void testUpercaseNameScript() throws ParseException, IOException {
+ final String scriptSrc = "component {\r\n"
+ + "function test() {\r\n"
+ + " var FIRSTNAME = \"Fred\";\r\n"
+ + " LAST_NAME = \"Smith\";\r\n"
+ + " names = {};\r\n"
+ + " name.FIRST = \"Fred\";\r\n"
+ + " NAMES[1] = \"Fred\";\r\n"
+ + "}\r\n"
+ + "}";
+ cfBugs.process(scriptSrc, "test");
+ final List result = cfBugs.getBugs().getBugList().values().iterator().next();
+ assertEquals(4, result.size());
+ assertEquals("VAR_ALLCAPS_NAME", result.get(0).getMessageCode());
+ assertEquals(3, result.get(0).getLine());
+ assertEquals("VAR_ALLCAPS_NAME", result.get(1).getMessageCode());
+ assertEquals(4, result.get(1).getLine());
+ assertEquals("VAR_ALLCAPS_NAME", result.get(2).getMessageCode());
+ assertEquals(6, result.get(2).getLine());
+ assertEquals("VAR_ALLCAPS_NAME", result.get(3).getMessageCode());
+ assertEquals(7, result.get(3).getLine());
+ }
+
+ @Test
+ public void invalidCharsInNameScript() throws ParseException, IOException {
+ final String scriptSrc = "component {\r\n"
+ + "function test() {\r\n"
+ + " var $name = \"Fred\";\r\n"
+ + " last$name = \"Smith\";\r\n"
+ + " last.$name = \"Smith\";\r\n"
+ + "}\r\n"
+ + "}";
+ cfBugs.process(scriptSrc, "test");
+ final List result = cfBugs.getBugs().getBugList().values().iterator().next();
+ assertEquals(3, result.size());
+ assertEquals("VAR_INVALID_NAME", result.get(0).getMessageCode());
+ assertEquals(3, result.get(0).getLine());
+ assertEquals("VAR_INVALID_NAME", result.get(1).getMessageCode());
+ assertEquals(4, result.get(1).getLine());
+ assertEquals("VAR_INVALID_NAME", result.get(2).getMessageCode());
+ assertEquals(5, result.get(2).getLine());
+ }
+
+ @Test
+ public void nameEndsInNumberScript() throws ParseException, IOException {
+ final String scriptSrc = "component {\r\n"
+ + "function test() {\r\n"
+ + " name_1 = \"Fred\";\r\n"
+ + " name2 = \"Smith\";\r\n"
+ + " last.name1 = \"Fred\";\r\n"
+ + "}\r\n"
+ + "}";
+ cfBugs.process(scriptSrc, "test");
+ final List result = cfBugs.getBugs().getBugList().values().iterator().next();
+ assertEquals(3, result.size());
+ assertEquals("VAR_INVALID_NAME", result.get(0).getMessageCode());
+ assertEquals(3, result.get(0).getLine());
+ assertEquals("VAR_INVALID_NAME", result.get(1).getMessageCode());
+ assertEquals(4, result.get(1).getLine());
+ assertEquals("VAR_INVALID_NAME", result.get(2).getMessageCode());
+ assertEquals(5, result.get(2).getLine());
+ }
+
+ @Test
+ public void nameTooShortScript() throws ParseException, IOException {
+ final String scriptSrc = "component {\r\n"
+ + "function test() {\r\n"
+ + " a = \"Fred\";\r\n"
+ + " b = \"Smith\";\r\n"
+ + " last.a = \"Fred\";\r\n"
+ + "}\r\n"
+ + "}";
+ cfBugs.process(scriptSrc, "test");
+ final List result = cfBugs.getBugs().getBugList().values().iterator().next();
+ assertEquals(3, result.size());
+ assertEquals("VAR_TOO_SHORT", result.get(0).getMessageCode());
+ assertEquals(3, result.get(0).getLine());
+ assertEquals("VAR_TOO_SHORT", result.get(1).getMessageCode());
+ assertEquals(4, result.get(1).getLine());
+ assertEquals("VAR_TOO_SHORT", result.get(2).getMessageCode());
+ assertEquals(5, result.get(2).getLine());
+ }
+
+ @Test
+ public void nameTooLongScript() throws ParseException, IOException {
+ final String scriptSrc = "component {\r\n"
+ + "function test() {\r\n"
+ + " isaveryveryverylongvariablename = \"Fred\";\r\n"
+ + " isa.veryveryverylongvariablename = \"Fred\";\r\n"
+ + "}\r\n"
+ + "}";
+ cfBugs.process(scriptSrc, "test");
+ final List result = cfBugs.getBugs().getBugList().values().iterator().next();
+ assertEquals(2, result.size());
+ assertEquals("VAR_TOO_LONG", result.get(0).getMessageCode());
+ assertEquals(3, result.get(0).getLine());
+ assertEquals("VAR_TOO_LONG", result.get(1).getMessageCode());
+ assertEquals(4, result.get(1).getLine());
+ }
+
+ @Test
+ public void nameTooWordyScript() throws ParseException, IOException {
+ final String scriptSrc = "component {\r\n"
+ + "function test() {\r\n"
+ + " nameIsFarTooWordy = \"Fred\";\r\n"
+ + " nameIsOK = \"Fred\";\r\n"
+ + " name.isAlsoFarTooWordy = \"Fred\";\r\n"
+ + "}\r\n"
+ + "}";
+ cfBugs.process(scriptSrc, "test");
+ final List result = cfBugs.getBugs().getBugList().values().iterator().next();
+ assertEquals(2, result.size());
+ assertEquals("VAR_TOO_WORDY", result.get(0).getMessageCode());
+ assertEquals(3, result.get(0).getLine());
+ assertEquals("VAR_TOO_WORDY", result.get(1).getMessageCode());
+ assertEquals(5, result.get(1).getLine());
+ }
+
+ @Test
+ public void nameIsTemporyScript() throws ParseException, IOException {
+ final String scriptSrc = "component {\r\n"
+ + "function test() {\r\n"
+ + " temp = \"Fred\";\r\n"
+ + " name.temp = \"Fred\";\r\n"
+ + " obj = \"Fred\";\r\n"
+ + " struct = \"Fred\";\r\n"
+ + " tempName = \"Fred\";\r\n"
+ + " nameObj = \"Fred\";\r\n"
+ + " nameString = \"Fred\";\r\n"
+ + "}\r\n"
+ + "}";
+ cfBugs.process(scriptSrc, "test");
+ final List result = cfBugs.getBugs().getBugList().get("VAR_IS_TEMPORARY");
+ assertEquals(7, result.size());
+ assertEquals("VAR_IS_TEMPORARY", result.get(0).getMessageCode());
+ assertEquals(3, result.get(0).getLine());
+ assertEquals("VAR_IS_TEMPORARY", result.get(1).getMessageCode());
+ assertEquals(4, result.get(1).getLine());
+ assertEquals("VAR_IS_TEMPORARY", result.get(2).getMessageCode());
+ assertEquals(5, result.get(2).getLine());
+ assertEquals("VAR_IS_TEMPORARY", result.get(3).getMessageCode());
+ assertEquals(6, result.get(3).getLine());
+ assertEquals("VAR_IS_TEMPORARY", result.get(4).getMessageCode());
+ assertEquals(7, result.get(4).getLine());
+ assertEquals("VAR_IS_TEMPORARY", result.get(5).getMessageCode());
+ assertEquals(8, result.get(5).getLine());
+ assertEquals("VAR_IS_TEMPORARY", result.get(6).getMessageCode());
+ assertEquals(9, result.get(6).getLine());
+ }
+
+ @Test
+ public void nameHasPrefixOrPostfixScript() throws ParseException, IOException {
+ final String scriptSrc = "component {\r\n"
+ + "function test() {\r\n"
+ + " sName = \"Fred\";\r\n"
+ + " nameSt = {first:\"Fred\"};\r\n"
+ + " oName = {first:\"Fred\"};\r\n"
+ + " bOff = true;\r\n"
+ + " arrNames = [\"Fred\"];\r\n"
+ + " thisName = \"Fred\";\r\n"
+ + " myName = \"Fred\";\r\n"
+ + "}\r\n"
+ + "}";
+ cfBugs.process(scriptSrc, "test");
+ final List result = cfBugs.getBugs().getBugList().values().iterator().next();
+ assertEquals(7, result.size());
+ assertEquals("VAR_HAS_PREFIX_OR_POSTFIX", result.get(0).getMessageCode());
+ assertEquals(3, result.get(0).getLine());
+ assertEquals("VAR_HAS_PREFIX_OR_POSTFIX", result.get(1).getMessageCode());
+ assertEquals(4, result.get(1).getLine());
+ assertEquals("VAR_HAS_PREFIX_OR_POSTFIX", result.get(2).getMessageCode());
+ assertEquals(5, result.get(2).getLine());
+ assertEquals("VAR_HAS_PREFIX_OR_POSTFIX", result.get(3).getMessageCode());
+ assertEquals(6, result.get(3).getLine());
+ assertEquals("VAR_HAS_PREFIX_OR_POSTFIX", result.get(4).getMessageCode());
+ assertEquals(7, result.get(4).getLine());
+ assertEquals("VAR_HAS_PREFIX_OR_POSTFIX", result.get(5).getMessageCode());
+ assertEquals(8, result.get(5).getLine());
+ assertEquals("VAR_HAS_PREFIX_OR_POSTFIX", result.get(6).getMessageCode());
+ assertEquals(9, result.get(6).getLine());
+ }
+
+}
diff --git a/src/test/java/com/cflint/TestValidNames.java b/src/test/java/com/cflint/TestValidNames.java
new file mode 100644
index 000000000..e0fcdd05d
--- /dev/null
+++ b/src/test/java/com/cflint/TestValidNames.java
@@ -0,0 +1,158 @@
+package com.cflint;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+
+import java.io.IOException;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.cflint.plugins.core.ValidName;
+
+public class TestValidNames {
+
+ private ValidName name;
+
+ @Before
+ public void setUp() {
+ name = new ValidName(3, 20, 3);
+ }
+
+ @Test
+ public void testInvalid() {
+ assertFalse(name.isInvalid("camelCase"));
+ assertFalse(name.isInvalid("product_id"));
+ assertFalse(name.isInvalid("size"));
+ assertFalse(name.isInvalid("lowercase"));
+ assertFalse(name.isInvalid("UPPERCASE"));
+ assertFalse(name.isInvalid("99_bottles_of_beer"));
+
+ assertTrue(name.isInvalid("UppperCaseCamel"));
+ assertTrue(name.isInvalid("endsInNumber99"));
+ }
+
+ @Test
+ public void testValidChars() {
+ assertTrue(name.validChars("camelCase"));
+ assertTrue(name.validChars("product_id"));
+ assertTrue(name.validChars("99_bottles_of_beer"));
+
+ assertFalse(name.validChars("no$items"));
+ assertFalse(name.validChars("no-items"));
+ assertFalse(name.validChars("no+items"));
+ }
+
+ @Test
+ public void testIsCamelCaseLower() {
+ assertTrue(name.isCamelCaseLower("product"));
+ assertTrue(name.isCamelCaseLower("camelCase"));
+ assertTrue(name.isCamelCaseLower("product4G"));
+ assertTrue(name.isCamelCaseLower("productID"));
+ assertTrue(name.isCamelCaseLower("requestViaHTTPS"));
+ assertTrue(name.isCamelCaseLower("myURLRequest"));
+
+ assertFalse(name.isCamelCaseLower("product_id"));
+ assertFalse(name.isCamelCaseLower("UpperCase"));
+ assertFalse(name.isCamelCaseLower("Uppercase"));
+ assertFalse(name.isCamelCaseLower("ProductID"));
+ assertFalse(name.isCamelCaseLower("PRODUCTID"));
+ }
+
+ @Test
+ public void testIsCamelCaseUpper() {
+ assertTrue(name.isCamelCaseUpper("Product"));
+ assertTrue(name.isCamelCaseUpper("PamelCase"));
+ assertTrue(name.isCamelCaseUpper("Product4G"));
+ assertTrue(name.isCamelCaseUpper("ProductID"));
+ assertTrue(name.isCamelCaseUpper("RequestViaHTTPS"));
+ assertTrue(name.isCamelCaseUpper("MyURLRequest"));
+
+ assertFalse(name.isCamelCaseUpper("product"));
+ assertFalse(name.isCamelCaseUpper("Product_id"));
+ assertFalse(name.isCamelCaseUpper("Product_Id"));
+ assertFalse(name.isCamelCaseUpper("PRODUCTID"));
+ }
+
+ @Test
+ public void testUsesUnderscores() {
+ assertTrue(name.usesUnderscores("product_name"));
+ assertTrue(name.usesUnderscores("_atstart"));
+ assertTrue(name.usesUnderscores("atend_"));
+ assertTrue(name.usesUnderscores("lots_of_under_scores"));
+
+ assertFalse(name.usesUnderscores("productName"));
+ assertFalse(name.usesUnderscores("productname"));
+ }
+
+ @Test
+ public void testEndsInNumber() {
+ assertTrue(name.endsInNumber("endsInNumber99"));
+ assertTrue(name.endsInNumber("temp2"));
+
+ assertFalse(name.endsInNumber("productName"));
+ assertFalse(name.endsInNumber("phone4G"));
+ assertFalse(name.endsInNumber("99beers"));
+ }
+
+ @Test
+ public void testTooShort() {
+ assertTrue(name.tooShort("a"));
+ assertTrue(name.tooShort("to"));
+
+ assertFalse(name.tooShort("the"));
+ assertFalse(name.tooShort("chars"));
+ assertFalse(name.tooShort("averylongname"));
+ }
+
+ @Test
+ public void testTooLong() {
+ assertTrue(name.tooLong("123456789012345678901"));
+ assertTrue(name.tooLong("aVeryLongNameThatIsTooLong"));
+
+ assertFalse(name.tooLong("shortName"));
+ assertFalse(name.tooLong("short_name"));
+ assertFalse(name.tooLong("12345678901234567890"));
+ }
+
+
+ @Test
+ public void testTooWordy() {
+ assertTrue(name.tooWordy("thisIsAVeryWordyName"));
+ assertTrue(name.tooWordy("alsoFarTooWordy"));
+
+ assertFalse(name.tooWordy("ProductName"));
+ assertFalse(name.tooWordy("aSimpleName"));
+ assertFalse(name.tooWordy("simple"));
+ }
+
+ @Test
+ public void testIsTemporary() {
+ assertTrue(name.isTemporary("temp"));
+ assertTrue(name.isTemporary("tmp"));
+ assertTrue(name.isTemporary("myVar"));
+ assertTrue(name.isTemporary("aFunc"));
+ assertTrue(name.isTemporary("nameObj"));
+ assertTrue(name.isTemporary("name_obj"));
+ assertTrue(name.isTemporary("tmp_array"));
+
+ assertFalse(name.isTemporary("temperature"));
+ assertFalse(name.isTemporary("productName"));
+ assertFalse(name.isTemporary("first_name"));
+ }
+
+ @Test
+ public void testHasPrefixOrPostfix() {
+ assertTrue(name.hasPrefixOrPostfix("stName"));
+ assertTrue(name.hasPrefixOrPostfix("oPerson"));
+ assertTrue(name.hasPrefixOrPostfix("qGet"));
+ assertTrue(name.hasPrefixOrPostfix("nameStr"));
+ assertTrue(name.hasPrefixOrPostfix("bValid"));
+
+ assertFalse(name.isTemporary("temperature"));
+ assertFalse(name.isTemporary("strength"));
+ assertFalse(name.isTemporary("argument"));
+ assertFalse(name.isTemporary("first_name"));
+ }
+}